void CannyEdgeDetector::HysteresisPixel(long int tx, long int ty,uint8_t highThreshold, uint8_t lowThreshold)
{
    _DEBUG(LOG_INFO(main)<<"x:"<<tx<<" y:"<<ty);
    if (GetPixelValue(tx, ty) >= highThreshold) {
        SetPixelValue(tx, ty, 255);
        /*if(isPara)
            this->HysteresisRecursion_para(x, y, lowThreshold);
        else
            this->*/
        HysteresisRecursion(tx, ty, lowThreshold);
    }
}
void CannyEdgeDetector::Hysteresis(uint8_t lowThreshold, uint8_t highThreshold)
{
    chrono::time_point<chrono::system_clock> start, end;
    start = chrono::system_clock::now();
    if(isPara)
    {
        this->ParaHysteresis(lowThreshold,highThreshold);
    }
    else {
        bool no_modify = false;
        //while(!no_modify)
        {
            no_modify = true;
            for (x = 0; x < height; x++) {
                for (y = 0; y < width; y++) {
                    if (GetPixelValue(x, y) >= highThreshold) {
                        if(GetPixelValue(x, y) != 255)
                            no_modify = false;
                        SetPixelValue(x, y, 255);
                        /*if(isPara)
                            this->HysteresisRecursion_para(x, y, lowThreshold);
                        else
                            this->*/
                        no_modify = HysteresisRecursion(x, y, lowThreshold);
                    }
                }
            }
        }
    }
    end = chrono::system_clock::now();
    hysteresis_time = chrono::duration_cast<chrono::microseconds>(end-start).count();

    for (x = 0; x < height; x++) {//no big differences?
        for (y = 0; y < width; y++) {
            if (GetPixelValue(x, y) != 255) {
                SetPixelValue(x, y, 0);
            }
        }
    }
}
Пример #3
0
bool HorizonExtend::Extend(IMG image)
{
	unsigned char*	pImgBase = NULL; 
	PVPAT			VPAT 	 = NULL; 
	GetImageVPA (image, 0, (LPVOID *)&pImgBase, (PVPAT*)&VPAT); 
	
	long width	= ImageWidth	(image);
	long height = ImageHeight	(image);
	
	for (long y=0; y< height; ++y) 
	{ 
		unsigned char*	pLineAddr = pImgBase + VPAT[y].YEntry; 
		TwoEndInfo endInfo = GetEndInfo(pLineAddr, VPAT, width);
		SetPixelValue(pLineAddr, VPAT, width, endInfo);
	} 
	
	return true;
}
bool CannyEdgeDetector::HysteresisRecursion(long tx, long ty, uint8_t lowThreshold)
{
    uint8_t value = 0;
    bool no_modify = true;
    for (long x1 = tx - 1; x1 <= tx + 1; x1++) {
        for (long y1 = ty - 1; y1 <= ty + 1; y1++) {
            if ((x1 < height) & (y1 < width) & (x1 >= 0) & (y1 >= 0)
                    & (x1 != tx) & (y1 != ty)) {
                value = GetPixelValue(x1, y1);
                if (value != 255) {
                    if (value >= lowThreshold) {
                        SetPixelValue(x1, y1, 255);
                        no_modify = false;
//                         this->HysteresisRecursion(x1, y1, lowThreshold);
                    }
                }
            }
        }
    }
    return no_modify;
}
void CannyEdgeDetector::HysteresisRecursion_para(long x, long y, uint8_t lowThreshold)
{
    std::vector<std::pair<long,long>> neighbor_vecs;
    for (long x1 = x - 1; x1 <= x + 1; x1++) {
        for (long y1 = y - 1; y1 <= y + 1; y1++) {
            if ((x1 < height) & (y1 < width) & (x1 >= 0) & (y1 >= 0)
                    & (x1 != x) & (y1 != y)) {
                neighbor_vecs.push_back(std::make_pair(x1,y1));
            }
        }
    }
    ff::paragroup neighbor_pg;
    neighbor_pg.for_each(neighbor_vecs.begin(), neighbor_vecs.end(),
    [&lowThreshold,this](std::pair<long,long> pixel_pair) {
        uint8_t value = GetPixelValue(pixel_pair.first,pixel_pair.second);
        if(value != 255 && value >= lowThreshold) {
            SetPixelValue(pixel_pair.first,pixel_pair.second,255);
//             this->HysteresisRecursion_para(pixel_pair.first,pixel_pair.second,lowThreshold);
        }
    });
    ff_wait(all(neighbor_pg));
}
void CannyEdgeDetector::PreProcessImage(float sigma)
{
    // Finding mask size with given sigma.
    mask_size = 2 * round(sqrt(-log(0.3) * 2 * sigma * sigma)) + 1;
    mask_halfsize = mask_size / 2;

    // Enlarging workspace bitmap width and height.
    height += mask_halfsize * 2;
    width += mask_halfsize * 2;
    // Working area.
    workspace_bitmap = new uint8_t[height * width];

    // Edge information arrays.
    edge_magnitude = new float[width * height];
    edge_direction = new uint8_t[width * height];

    // Zeroing direction array.
    for (x = 0; x < height; x++) {
        for (y = 0; y < width; y++) {
            edge_direction[x * width + y] = 0;
        }
    }

    // Copying image data into work area.
    for (x = 0; x < height; x++) {
        for (y = 0; y < width; y++) {
            // Upper left corner.
            if (x < mask_halfsize &&  y < mask_halfsize) {
                SetPixelValue(x, y, *(source_bitmap));
            }
            // Bottom left corner.
            else if (x >= height - mask_halfsize && y < mask_halfsize) {
                SetPixelValue(x, y, *(source_bitmap + (height - 2 * mask_halfsize - 1) * 3 * (width - 2 * mask_halfsize)));
            }
            // Upper right corner.
            else if (x < mask_halfsize && y >= width - mask_halfsize) {
                SetPixelValue(x, y, *(source_bitmap + 3 * (width - 2 * mask_halfsize - 1)));
            }
            // Bottom right corner.
            else if (x >= height - mask_halfsize && y >= width - mask_halfsize) {
                SetPixelValue(x, y, *(source_bitmap +
                                      (height - 2 * mask_halfsize - 1) * 3 * (width - 2 * mask_halfsize) + 3 * (width - 2 * mask_halfsize - 1)));
            }
            // Upper beam.
            else if (x < mask_halfsize) {
                SetPixelValue(x, y, *(source_bitmap + 3 * (y - mask_halfsize)));
            }
            // Bottom beam.
            else if (x >= height -  mask_halfsize) {
                SetPixelValue(x, y, *(source_bitmap +
                                      (height - 2 * mask_halfsize - 1) * 3 * (width - 2 * mask_halfsize) + 3 * (y - mask_halfsize)));
            }
            // Left beam.
            else if (y < mask_halfsize) {
                SetPixelValue(x, y, *(source_bitmap +
                                      (x - mask_halfsize) * 3 * (width - 2 * mask_halfsize)));
            }
            // Right beam.
            else if (y >= width - mask_halfsize) {
                SetPixelValue(x, y, *(source_bitmap +
                                      (x - mask_halfsize) * 3 * (width - 2 * mask_halfsize) + 3 * (width - 2 * mask_halfsize - 1)));
            }
            // The rest of the image.
            else {
                SetPixelValue(x, y, *(source_bitmap +
                                      (x - mask_halfsize) * 3 * (width - 2 * mask_halfsize) + 3 * (y - mask_halfsize)));
            }
        }
    }
}
void CannyEdgeDetector::NonMaxSuppression()
{
    float pixel_1 = 0;
    float pixel_2 = 0;
    float pixel;

    for (x = 1; x < height - 1; x++) {
        for (y = 1; y < width - 1; y++) {
            if (edge_direction[x * width + y] == 0) {
                pixel_1 = edge_magnitude[(x + 1) * width + y];
                pixel_2 = edge_magnitude[(x - 1) * width + y];
            } else if (edge_direction[x * width + y] == 45) {
                pixel_1 = edge_magnitude[(x + 1) * width + y - 1];
                pixel_2 = edge_magnitude[(x - 1) * width + y + 1];
            } else if (edge_direction[x * width + y] == 90) {
                pixel_1 = edge_magnitude[x * width + y - 1];
                pixel_2 = edge_magnitude[x * width + y + 1];
            } else if (edge_direction[x * width + y] == 135) {
                pixel_1 = edge_magnitude[(x + 1) * width + y + 1];
                pixel_2 = edge_magnitude[(x - 1) * width + y - 1];
            }
            pixel = edge_magnitude[x * width + y];
            if ((pixel >= pixel_1) && (pixel >= pixel_2)) {
                SetPixelValue(x, y, pixel);
            } else {
                SetPixelValue(x, y, 0);
            }
        }
    }

    bool change = true;
    while (change) {
        change = false;
        for (x = 1; x < height - 1; x++) {
            for (y = 1; y < width - 1; y++) {
                if (GetPixelValue(x, y) == 255) {
                    if (GetPixelValue(x + 1, y) == 128) {
                        change = true;
                        SetPixelValue(x + 1, y, 255);
                    }
                    if (GetPixelValue(x - 1, y) == 128) {
                        change = true;
                        SetPixelValue(x - 1, y, 255);
                    }
                    if (GetPixelValue(x, y + 1) == 128) {
                        change = true;
                        SetPixelValue(x, y + 1, 255);
                    }
                    if (GetPixelValue(x, y - 1) == 128) {
                        change = true;
                        SetPixelValue(x, y - 1, 255);
                    }
                    if (GetPixelValue(x + 1, y + 1) == 128) {
                        change = true;
                        SetPixelValue(x + 1, y + 1, 255);
                    }
                    if (GetPixelValue(x - 1, y - 1) == 128) {
                        change = true;
                        SetPixelValue(x - 1, y - 1, 255);
                    }
                    if (GetPixelValue(x - 1, y + 1) == 128) {
                        change = true;
                        SetPixelValue(x - 1, y + 1, 255);
                    }
                    if (GetPixelValue(x + 1, y - 1) == 128) {
                        change = true;
                        SetPixelValue(x + 1, y - 1, 255);
                    }
                }
            }
        }
        if (change) {
            for (x = height - 2; x > 0; x--) {
                for (y = width - 2; y > 0; y--) {
                    if (GetPixelValue(x, y) == 255) {
                        if (GetPixelValue(x + 1, y) == 128) {
                            change = true;
                            SetPixelValue(x + 1, y, 255);
                        }
                        if (GetPixelValue(x - 1, y) == 128) {
                            change = true;
                            SetPixelValue(x - 1, y, 255);
                        }
                        if (GetPixelValue(x, y + 1) == 128) {
                            change = true;
                            SetPixelValue(x, y + 1, 255);
                        }
                        if (GetPixelValue(x, y - 1) == 128) {
                            change = true;
                            SetPixelValue(x, y - 1, 255);
                        }
                        if (GetPixelValue(x + 1, y + 1) == 128) {
                            change = true;
                            SetPixelValue(x + 1, y + 1, 255);
                        }
                        if (GetPixelValue(x - 1, y - 1) == 128) {
                            change = true;
                            SetPixelValue(x - 1, y - 1, 255);
                        }
                        if (GetPixelValue(x - 1, y + 1) == 128) {
                            change = true;
                            SetPixelValue(x - 1, y + 1, 255);
                        }
                        if (GetPixelValue(x + 1, y - 1) == 128) {
                            change = true;
                            SetPixelValue(x + 1, y - 1, 255);
                        }
                    }
                }
            }
        }
    }

    // Suppression
    for (x = 0; x < height; x++) {
        for (y = 0; y < width; y++) {
            if (GetPixelValue(x, y) == 128) {
                SetPixelValue(x, y, 0);
            }
        }
    }
}
void CannyEdgeDetector::EdgeDetection()
{
    // Sobel masks.
    float Gx[9];
    Gx[0] = 1.0;
    Gx[1] = 0.0;
    Gx[2] = -1.0;
    Gx[3] = 2.0;
    Gx[4] = 0.0;
    Gx[5] = -2.0;
    Gx[6] = 1.0;
    Gx[7] = 0.0;
    Gx[8] = -1.0;
    float Gy[9];
    Gy[0] = -1.0;
    Gy[1] = -2.0;
    Gy[2] = -1.0;
    Gy[3] =  0.0;
    Gy[4] =  0.0;
    Gy[5] =  0.0;
    Gy[6] =  1.0;
    Gy[7] =  2.0;
    Gy[8] =  1.0;

    float value_gx, value_gy;

    float max = 0.0;
    float angle = 0.0;

    // Convolution.
    for (x = 0; x < height; x++) {
        for (y = 0; y < width; y++) {
            value_gx = 0.0;
            value_gy = 0.0;

            for (int k = 0; k < 3; k++) {
                for (int l = 0; l < 3; l++) {
                    value_gx += Gx[l * 3 + k] * GetPixelValue((x + 1) + (1 - k),
                                (y + 1) + (1 - l));
                    value_gy += Gy[l * 3 + k] * GetPixelValue((x + 1) + (1 - k),
                                (y + 1) + (1 - l));
                }
            }

            edge_magnitude[x * width + y] = sqrt(value_gx * value_gx + value_gy * value_gy) / 4.0;

            // Maximum magnitude.
            max = edge_magnitude[x * width + y] > max ? edge_magnitude[x * width + y] : max;

            // Angle calculation.
            if ((value_gx != 0.0) || (value_gy != 0.0)) {
                angle = atan2(value_gy, value_gx) * 180.0 / PI;
            } else {
                angle = 0.0;
            }
            if (((angle > -22.5) && (angle <= 22.5)) ||
                    ((angle > 157.5) && (angle <= -157.5))) {
                edge_direction[x * width + y] = 0;
            } else if (((angle > 22.5) && (angle <= 67.5)) ||
                       ((angle > -157.5) && (angle <= -112.5))) {
                edge_direction[x * width + y] = 45;
            } else if (((angle > 67.5) && (angle <= 112.5)) ||
                       ((angle > -112.5) && (angle <= -67.5))) {
                edge_direction[x * width + y] = 90;
            } else if (((angle > 112.5) && (angle <= 157.5)) ||
                       ((angle > -67.5) && (angle <= -22.5))) {
                edge_direction[x * width + y] = 135;
            }
        }
    }

    for (x = 0; x < height; x++) {
        for (y = 0; y < width; y++) {
            edge_magnitude[x * width + y] =
                255.0f * edge_magnitude[x * width + y] / max;
            SetPixelValue(x, y, edge_magnitude[x * width + y]);
        }
    }
}