Shared Samples

Try out source code samples stored in Bitbucket repositories.
Showing results for 
Search instead for 
Do you mean 

Job imageModify: read and modify existing pixel value

by Technical Evangelist on ‎09-08-2015 10:33 AM - edited on ‎03-29-2016 11:29 AM by Anonymous (757 Views)

Example Type

Job

 

 

Purpose

 

This example shows how to read an existing image, modify existing pixel value and write the output to a new image.

 

Files

 

imageModify.c              (C source code)

imageModify.eml         (EML script)

imageModify.dsp          (Visual C++ Project)(Windows Only)

 

 

Description

 

The imageModify example demonstrates how to access the actual pixel values of an image. To get specific pixel values of an image, it is necessary to read the values into a buffer called the Eimg_PixelRect and then access the pixel values from within that buffer. This example shows how to access the pixel values and modify these values by applying a linear scaling to the image.

The output pixel values will be calculated using the formula outputpixelvalue = inputpixelvalue × scalefactor + offset.

Egda_PixelType determines the "depth" of the data and what kind of data a pixel can hold. This affects  two aspects of this example:

1) The PixelRect is comprised of doubles (Egda_Type_F64) and allows all pixel types (with the exception of complex pixels) to be handled. The Eimg library automatically handles the type casting.

2) The output image will be of a user specified type and as such if the results exceed the range of the output data then the values will be clipped to the possible range of the output data as specified by the user.

 

 

Command Line Options

 

imagemodify -in <inputfile> -out <outputfile> -s [<scalefactor>] -o [<offset>] -p <pixeltype> [-m <0|1>]

 

 

-in[put]

 Input raster file.

 

-out[put]

 Output raster file.

 

-s[cale[factor]]

 This value will be multiplied by the input raster pixel values.

 

-o[ff[set]]

 This value will be added to the input raster pixel values.

 

-p[ixel[type]]

 Pixel type of output image. This is important, since it is the user's responsibility to choose a pixel type sufficiently large to hold the output data values.

 

-m

 Specifies whether or not to meter the process. 0 is no and 1 (default) is yes.

 

 

Interface

 demo.jpg

 

Output

The input file is changed according to the scale factor, offset and output type to produce the modified output file.

 

Notes

The user is responsible for ensuring that the output pixel type is sufficient to hold the modified data.

This program does not maintain projection and map information from input file to output file.

 

Source Code

https://bitbucket.org/HGDN/hgdn_erdas_imagine/src/e1ade3b7d148b0f2f1aa6427044dfa4bce6226ee/Job_image...

 

 

/************************************************************************
*************************************************************************
 Job: imageModify

 Purpose: This example shows how to read an existing image, modify 
 existing pixel values and write the output to a new image. 

 Calling syntax:

 imagemodify -in <inputfile> -out <outputfile>[-s <scalefactor>]
 [-o <offset>] -p <pixeltype> -m <1 or 0>

 e.g.
 imagemodify -in "$IMAGINE_HOME/examples/lanier.img" 
 -out "$IMAGINE_HOME/examples/temp.img" -s 0.5 -p U8 -m 1

*************************************************************************
*************************************************************************/

/*
**  Standard Includes
*/

#include <stdio.h>


/*
**  Toolkit Includes
*/

#include <earg.h>
#include <eimg.h>
#include <eerr.h>
#include <eint.h>
#include <esec.h>
#include <esmg.h>
#include <emsc.h>
#include <emet.h>
#include <estr.h>

/*
**  Error checking Macros
*/

#define EFS1( msg, arg ) EERR_FATAL_SET_1( __LINE__, msg, arg )
#define EFS0( msg ) EERR_FATAL_SET_0( __LINE__, msg )
#define ES0( e, msg ) EERR_SHOW_0( e, EERR_DEBUG, __LINE__, msg )


/*
**  Global Functions
*/
static void jobMain(int, char **);
static void set_input(int, char **);
static void set_output(int, char **);
static void set_scalefactor(int, char **);
static void set_offset(int, char **);
static void set_pixel(int, char **);
static void set_meter(int, char **);



/*
** Command line arguments: These are the arguments that are
** used in "earg_DoArgs( command, argc, argv, &lclerr )" function if the
** flag is used.
**
** Each option you want to specify must be a seperate function. That function
** should set a global variable that will in turn be used by the main part
** the function.
*/

Earg_Cmd command[] =
{
    set_input,          "-in[put] %s",          "", NULL,
    set_output,         "-out[put] %s",         "", NULL,
    set_scalefactor,    "-s[cale[factor]] [%f]","", NULL,
    set_offset      ,   "-o[ff[set]] [%f]",     "", NULL,
    set_pixel,          "-p[ixel[type]] %s",    "", NULL,
    set_meter,          "-m[eter] [%d]",        "", NULL,
    jobMain,            "imagemodify",          "", NULL,

    EARG_END
};

/*
**  Global Variables(not the best way but the most straightforward)
*/
static char *input = NULL;
static char *output = NULL;
static char *scalefactor = NULL;
static char *offsetfactor = NULL;
static Egda_PixelType   pixeltype;
static Emet_MeterInfo *meter = NULL;
static int  rc = -1;


/*
**  Main entry point. This will call the DoArgs function that
** will get down to the business of actuall doing something.
*/
int
main(
    int argc,
    char **argv
)
{
    EERR_INIT("Modify Example:main", &lclerr, lclerr);

    (void)eint_InitToolkit((Emsc_Opaque**)&lclerr);
    EERR_CHECK(lclerr, EFS0("Error initializing the Toolkit"));
    
    esmg_JobInit("imageModify", &lclerr);
    EERR_CHECK(lclerr, EFS0("Error connecting to the session manager"));
    
    earg_DoArgs(command, argc, argv, &lclerr);
    ES0(lclerr, "An error has been found in the command line syntax!");
    
    esmg_JobEnd(&lclerr);
    ES0(lclerr, "An error was encountered while disconnecting from the session!");
    
cleanup:
    ES0(lclerr, "Errors reported by main");
    
    return rc;
}


/*
**  Input file
*/
static void
set_input(
    int argc,
    char **argv
)
{
    input = estr_Duplicate(argv[1]);
    return;
}


/*
**  output file
*/
static void
set_output(
    int argc,
    char **argv
)
{
    output = estr_Duplicate(argv[1]);
    return;
}

/*
**  scale
*/
static void
set_scalefactor(
    int argc,
    char **argv
)
{
    scalefactor = estr_Duplicate(argv[1]);
    return;
}


/*
**  offset
*/
static void
set_offset(
    int argc,
    char **argv
)
{
    offsetfactor = estr_Duplicate(argv[1]);
    return;
}

/*
** Set output pixeltype
*/
static void
set_pixel(
    int argc,
    char **argv
)
{
    if (argc == 1)
    {
        pixeltype = EGDA_TYPE_U8;
    }
    else
    {
        if (estr_Eqic(argv[1], "U8")) 
        {
            pixeltype = EGDA_TYPE_U8;
        }
        else if (estr_Eqic(argv[1], "S8"))
        {
            pixeltype = EGDA_TYPE_S8;
        }
        else if (estr_Eqic(argv[1], "U16"))
        {
            pixeltype = EGDA_TYPE_U16;
        }
        else if (estr_Eqic(argv[1], "S16"))
        {
            pixeltype = EGDA_TYPE_S16;
        }
        else
        {
            pixeltype = EGDA_TYPE_U8;
        }
    }
    return;
}

/*
**  meterinfo for metering
*/
static void
set_meter(
    int argc, 
    char **argv
)

{
    EERR_INIT("set meter", &lclerr, lclerr);
    
    if (argc == 1)
    {
        meter = emet_MeterInfoCreate("Starting...", "imageModify", NULL, &lclerr);
        EERR_CHECK(lclerr, EFS0("Error creating MeterInfo"));
    }
    
    else
    {
        if (estr_Eqic(argv[1], "0"))
        {
            meter = NULL;
        }
        else if (estr_Eqic(argv[1], "1"))
        {
            meter = emet_MeterInfoCreate("Starting...", "imageModify", NULL, &lclerr);
            EERR_CHECK(lclerr, EFS0("Error creating MeterInfo"));
        }
        else 
        {
            meter = NULL;
        }
    }
    
cleanup:
    
    return;
}

/*
**  The heart of the processing and where most of the action takes
** place since it may be the only required argument on the command line
*/

static void
jobMain(
    int argc,
    char **argv
)
{
    
    Eint_InitToolkitData    *erdinit = eint_GetInit();
    Estr_StringList         *layernames = NULL;
    Eimg_Layer              *inlayer = NULL, *outlayer = NULL;
    Eimg_PixelRect          *pixel = NULL;
    int                     status, i, j, row, col, blockcount;
    long                    layer, nlayers, xpixels, ypixels, xpixelsactual,
						    ypixelsactual, maxvalue;
    double                  *dblptr = NULL;
	double				    scale, offset;
    char                    *outlayername = NULL, *temptaskname = NULL;


    EERR_INIT("Modify Image example: jobMain", &lclerr, lclerr);

    /*
    ** Initialize metering options
    */
    emet_MeterInfoSet(meter, 0.0, 100.0, &lclerr);
    EERR_SHOW(lclerr, EERR_DEBUG);
    
    emet_MeterInfoPrint(meter, 0.0, &lclerr);
    EERR_SHOW(lclerr, EERR_DEBUG);
    
    /*
    ** Check to see if the input and output filename were received.
    */
    EERR_CHECK(!input, EFS0("You didn't specify a valid input file!"));
    EERR_CHECK(!output, EFS0("You didn't specify a valid output file!"));

    if (scalefactor)
        scale = atof(scalefactor);
    else
		scale = 1;
    
    if (offsetfactor)
        offset = atof(offsetfactor);
    else
		offset = 0;

    layernames = eimg_LayerGetNames(input, erdinit, &lclerr);
    EERR_CHECK(lclerr, EFS0("Error getting the layernames to work on!"));

    nlayers = layernames->count;
    EERR_CHECK(nlayers < 1, EFS0("Input image has invlaid number of layers!"));

    for (layer = 0; layer < nlayers; layer++)
    {
        maxvalue = 0;

        inlayer = eimg_LayerOpen(layernames->strings[layer], erdinit, &lclerr,
            EIMG_LAYER_OPTION_READONLY, EIMG_LAYER_OPTION_END);
        EERR_CHECK(lclerr, EFS0("Error opening Input layer!"));

        xpixels = inlayer->width;
        EERR_CHECK(!xpixels || xpixels < 1, EFS0("Image has no width?!"));

        ypixels = inlayer->height;
        EERR_CHECK(!ypixels || ypixels < 1, EFS0("Image has no height?!"));

        outlayername = estr_Sprintf(  NULL, "%s%s%d%s", &lclerr, output, "(:Layer_", layer ,")"  );
        EERR_CHECK(lclerr, EFS0("Error setting the output layer name!"));

        outlayer = eimg_LayerCreate(outlayername, inlayer->layerType, pixeltype,
            xpixels, ypixels, erdinit, &lclerr,
            EIMG_LAYER_OPTION_COMPUTE_STATS_ON_CLOSE, EIMG_LAYER_OPTION_END);
        EERR_CHECK(lclerr, EFS0("Error creating the output layer!"));

        pixel = eimg_PixelRectCreate(inlayer->blockWidth, inlayer->blockHeight,
            EGDA_TYPE_F64, &lclerr);
        EERR_CHECK(lclerr, EFS0("Error creating pixel buffer!"));
      
        emsc_Free(temptaskname);

        temptaskname = estr_Sprintf(NULL, "Modifying layer number %d of %d",
            &lclerr, layer + 1, nlayers);
        EERR_SHOW(lclerr, EERR_DEBUG);

        emet_MeterInfoChangeTaskName(meter, temptaskname, &lclerr);
        EERR_SHOW(lclerr, EERR_DEBUG);

        emet_MeterInfoSet(meter, 0.0, 100.0, &lclerr);
        EERR_SHOW(lclerr, EERR_DEBUG);

        blockcount = 0;


        for (row = 0; row < ypixels; row += inlayer->blockHeight)
        {
            ypixelsactual = EMSC_MIN(inlayer->blockHeight, ypixels - row);

            for (col = 0; col < xpixels; col += inlayer->blockWidth)
            {
                xpixelsactual = EMSC_MIN(inlayer->blockWidth, xpixels - col);

                /*
                **  Read a line from the input layer
                */
                eimg_LayerRead(inlayer, col, row, xpixelsactual, ypixelsactual,
                    pixel, &lclerr);
                EERR_CHECK(lclerr, EFS0("Can't read a line from the layer!"));


                /*
                **  Rescale data values
                */
                for (j = 0; j < ypixelsactual; j++)
                {
                    dblptr = (double *)(pixel->currentData + j*pixel->pitch);
                    for (i = 0; i < xpixelsactual; i++)
                    {
                        dblptr[i] = scale * dblptr[i] + offset;
                        if (dblptr[i] > maxvalue)
                            maxvalue = dblptr[i];
                    }
                }


                /*
                 *   Write the line to the output layer
                 */
                eimg_LayerWrite(outlayer, col, row, xpixelsactual,
                    ypixelsactual, pixel, &lclerr);
                EERR_CHECK(lclerr, EFS0("Can't write a line from the layer!"));


                /*
                **  Show percentage completion
                */
                blockcount++;

                emet_MeterInfoPrint(meter,
                    blockcount*100.0/(inlayer->blocksWide*inlayer->blocksHigh),
                    &lclerr);
                EERR_SHOW(lclerr, EERR_DEBUG);
            }
        }

        if (pixeltype == 3 && maxvalue > 256)
        {
            esmg_LogMessage(ESMG_LOG_TERSE, &lclerr,
                "Your max value of %ld exceeds Unsigned 8-bit!", maxvalue);
            EERR_SHOW(lclerr, EERR_DEBUG);
        }

        else if (pixeltype == 5 &&(maxvalue > 65535))
        {
            esmg_LogMessage(ESMG_LOG_TERSE, &lclerr,
                "Your max value of %ld exceeds Unsigned 16-bit!", maxvalue);
            EERR_SHOW(lclerr, EERR_DEBUG);
        }

        else if (pixeltype == 6 &&(maxvalue > 32767))
        {
            esmg_LogMessage(ESMG_LOG_TERSE, &lclerr,
                "Your max value of %ld exceeds Signed 16-bit!", maxvalue);
            EERR_SHOW(lclerr, EERR_DEBUG);
        }

        eimg_LayerClose(inlayer, &lclerr);
		inlayer = NULL;
        EERR_CHECK(lclerr, EFS0("Error Closing the currently open input layer!"));

        eimg_LayerClose(outlayer, &lclerr);
		outlayer = NULL;
        EERR_CHECK(lclerr, EFS0("Error Closing the currently open output layer!"));

        eimg_PixelRectDelete(pixel, &lclerr);
		pixel = NULL;
        EERR_CHECK(lclerr, EFS0("Error deleting the current pixel buffer!"));
    }

    rc = 0; /* everything is OK set to success */

    emet_MeterInfoPrint(meter, 100.0, &lclerr);
    EERR_SHOW(lclerr, EERR_DEBUG);
    
    emet_MeterInfoChangeTaskName(meter, "Finished!", &lclerr);
    EERR_SHOW(lclerr, EERR_DEBUG); 

cleanup:
    ES0(lclerr, "Errors reported by jobMain");

    estr_StringListDelete(layernames, &lclerr);
    EERR_SHOW(lclerr, EERR_DEBUG);

    eimg_LayerClose(inlayer, &lclerr);
    EERR_SHOW(lclerr, EERR_DEBUG);

    eimg_LayerClose(outlayer, &lclerr);
    EERR_SHOW(lclerr, EERR_DEBUG);
    
    eimg_PixelRectDelete(pixel, &lclerr);
    EERR_SHOW(lclerr, EERR_DEBUG);
    
    emet_MeterInfoDelete(meter, &lclerr);
    EERR_SHOW(lclerr, EERR_DEBUG);

    emsc_Free(input);
	emsc_Free(output);
	emsc_Free(scalefactor);
	emsc_Free(offsetfactor);
    emsc_Free(outlayername);   
    emsc_Free(temptaskname);

    return;
}

 

 

Overview
Contributors