Mirror image

Overview

Your own image conversion algorithm can be implemented as processing item.
This sample program shows how to create processing item, which makes mirror image.

Specification of processing item

Setting screen
Setting screen has only image window to show converted image, since this item has no parameters.

Measurement process
This item converts input image to mirror image.
Transformation of coordinate
In case the image conversion changes coordinate position, the transformation of coordinate is necessary.
There are 5 types of coordinate transformation.
(1) XY Position
(2) Angle
(3) Area size
(4) Distance
(5) Line parameters
This processing item flips over the image by X axis (X=0). Therefore the transformation is defined as below:

Original
After transformation
(1)
(X, Y)
(-X, Y)
(2)
Angle
-Agnle
(3)
Area
Area (no change)
(4)
Distance
Distance (no change)
(5)
AX + BY + C = 0
AX * (-1) + BY + C = 0
External Refence Data
This processing item does not define external reference data.

Implementation

1.Creating project
Create project according to tutorial refcreating project.
The parameters are as below.
Application Template
ImageProcess item
Identification name (Project name)
Mirror
After creation of the project, Visual Studio 2008 opens the project file.
2.Image processing
Implement the image processing algorithm.
It is also necessary to implement to set total judge result of this item.

MeasureProc.cpp
int CLASSNAME::MeasureProc(ProcUnit *ptrProcUnit)
{
        SETUPDATA       *ptrSetupData = ptrProcUnit->GetSetupData();
        MEASUREDATA     *ptrMeasData = ptrProcUnit->GetMeasureData();

        int ret = MeasureProcSub(ptrProcUnit);

        if (ret != NORMAL) {                                                                                                            '(6)
                if (ret == -3) {
                        ptrProcUnit->SetUnitJudge(JUDGE_IMAGEERROR);
                } else if (ret == -2) {
                        ptrProcUnit->SetUnitJudge(JUDGE_MEMORYERROR);
                } else {
                        ptrProcUnit->SetUnitJudge(JUDGE_NG);
                }
                return(-1);
        } else {
                ptrProcUnit->SetUnitJudge(JUDGE_OK);
                return NORMAL;
        }
}

int CLASSNAME::MeasureProcSub(ProcUnit *ptrProcUnit)
{
        SETUPDATA       *ptrSetupData = ptrProcUnit->GetSetupData();
        MEASUREDATA *ptrMeasureData = ptrProcUnit->GetMeasureData();

        IMAGE *ptrInImage = ptrProcUnit->GetMeasureImage(0);                        '(1)
        if (ptrInImage == NULL) {
                return(-2);
        }
        ptrProcUnit->ImageDataAlloc(0, sizeof(IMAGE) + ptrInImage->size);           '(2)
        IMAGE *ptrOutImage = ptrProcUnit->GetImageData(0);
        if (NULL == ptrOutImage) {
                return(-2);
        }

        ptrInImage = ptrProcUnit->GetMeasureImage(0);
        if (ptrInImage == NULL) {
                return(-2);
        }
        memcpy(ptrOutImage, ptrInImage, sizeof(IMAGE));                             '(3)

        int     judge = JUDGE_OK;

        int sizeX = ptrInImage->sizeX;
        int sizeY = ptrInImage->sizeY;
        
        if(ptrInImage->format == I_RGBCOLOR){                                       '(4)
                for (int i = 0; i < sizeY; i++) {
                
                        BYTE    *rs, *gs, *bs, *rd, *gd, *bd;
                        rs = (BYTE *)ptrInImage + sizeof(IMAGE) + sizeX * (i + 1) - 1;
                        gs = rs + sizeX * sizeY;
                        bs = gs + sizeX * sizeY;
                        rd = (BYTE *)ptrOutImage + sizeof(IMAGE) + sizeX * i;
                        gd = rd + sizeX * sizeY;
                        bd = gd + sizeX * sizeY;

                        for (int j = 0; j < sizeX; j++) {
                                *rd = *rs;
                                *gd = *gs;
                                *bd = *bs;
                                rs--; gs--; bs--;
                                rd++; gd++; bd++;
                        }
                }
        }else if(ptrInImage->format == I_MONOCHRO){

                for (int i = 0; i < sizeY; i++) {
                        BYTE    *rs, *rd;
                        rs = (BYTE *)ptrInImage + sizeof(IMAGE) + sizeX * (i + 1) - 1;
                        rd = (BYTE *)ptrOutImage + sizeof(IMAGE) + sizeX * i;
                        for (int j = 0; j < sizeX; j++) {
                                *rd = *rs;
                                rs--;
                                rd++;
                        }
                }
        }else{
                return -3;
        }

        ptrProcUnit->SetMeasureImage(0, 0);                                         '(5)
        return NORMAL;
}



(1)Acquire input image.
(2)Assign a memory area to store image for processing.
(3)Copy image data to assigned memory area.
(4)Implement algorithm to create mirror image.
Input image may be color or monochrome, so codes for both type of image format must be implemented.
(5)Set created mirror image as output of this item.
(6)Set total judge result of this item.
3.Image display
The codes for displaying converted image must be added to measurement display (MeasureDisp.cpp), image display for through mode (ThroughProc.cpp) and image display for setting screen (SetupDisp.cpp).
In case the project is created using the template of ImageProcess item, these codes are already implemented when the project is created.

MeasureDisp.cpp
int CLASSNAME::MeasureDispI(ProcUnit *ptrProcUnit, int subNo, ImageWindow *ptrImageWindow)
{
        ptrProcUnit->SetMeasureProcMask(TRUE);
        IMAGE *ptrImage = ptrProcUnit->GetImageData(0);
        ptrImageWindow->ImageDisp(ptrImage);
        ptrProcUnit->SetMeasureProcMask(FALSE);

    return(NORMAL);
}


ThroughProc.cpp
int CLASSNAME::ThroughProc(ProcUnit *ptrProcUnit)
{
        MeasureProcSub(ptrProcUnit);

        return(NORMAL);
}


SetupDisp.cpp
int CLASSNAME::SetupDisp(ProcUnit *ptrProcUnit, int subNo, ImageWindow *ptrImageWindow)
{
        SETUPDATA       *ptrSetupData = ptrProcUnit->GetSetupData();
        IMAGE   *image = ptrProcUnit->GetMeasureImage(0);
        if (image == NULL) {
                ptrImageWindow->ImageDisp(image);
                return -1;
        }

        ptrProcUnit->SetMeasureProcMask(TRUE);
        int ret = MeasureProcSub(ptrProcUnit);
        ptrProcUnit->SetMeasureProcMask(FALSE);

        if (ret == NORMAL) {
                image = ptrProcUnit->GetImageData(0);
        }
        ptrImageWindow->ImageDisp(image);

        return(NORMAL);
}

4.Coordinate transformation
This item transforms coordinate position described as above. These are the codes for converting coordinates.

Transform.cpp
int CLASSNAME::TransformXY(ProcUnit *ptrProcUnit, int imageNo, int mode, double srcX, double srcY, double *destX, double *destY)
{
        *destX = srcX * -1;
        *destY = srcY;

        return (NORMAL);
}

int CLASSNAME::TransformAngle(ProcUnit *ptrProcUnit, int imageNo, int mode, double srcAngle, double *destAngle)
{
        *destAngle = srcAngle * -1;

        return (NORMAL);
}

int CLASSNAME::TransformDist(ProcUnit *ptrProcUnit, int imageNo, int mode, double srcDist, double *destDist)
{
        *destDist = srcDist;

        return (NORMAL);
}

int CLASSNAME::TransformLine(ProcUnit *ptrProcUnit, int imageNo, int mode, 
                                double srcA, double srcB, double srcC, double *destA, double *destB, double *destC)
{
        *destA = srcA * -1;
        *destB = srcB;
        *destC = srcC;

        return (NORMAL);
}

Source codes

You can download full set of source codes of this item from this link.
refSource codes