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); } } } }
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]); } } }