int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Q_UNUSED(a) QImage inImage("lena.png"); inImage = inImage.convertToFormat(QImage::Format_RGB32); QImage outImage(inImage.size(), inImage.format()); // Here we configure the edge detector parameters. int radius = 1; qreal sigma = 1; qreal scaleXY = 1; qreal scaleW = 1; bool round = false; // Create gaussian denoise kernel. int kw; QVector<qreal> kernelX = edgeKernel(radius, sigma, scaleXY, scaleW, false, round, &kw); QVector<qreal> kernelY = edgeKernel(radius, sigma, scaleXY, scaleW, true, round, &kw); for (int y = 0; y < inImage.height(); y++) { const QRgb *iLine = (const QRgb *) inImage.constScanLine(y); QRgb *oLine = (QRgb *) outImage.scanLine(y); for (int x = 0; x < inImage.width(); x++) { qreal sumX = 0; qreal sumY = 0; // Apply kernel. for (int j = 0, pos = 0; j < kw; j++) { const QRgb *line = (const QRgb *) inImage.constScanLine(y + j - radius); if (y + j < radius || y + j >= radius + inImage.height()) continue; for (int i = 0; i < kw; i++, pos++) { if (x + i < radius || x + i >= radius + inImage.width()) continue; quint8 pixel = qGray(line[x + i - radius]); sumX += kernelX[pos] * pixel; sumY += kernelY[pos] * pixel; } } int grad = gradient(sumX, sumY, gradientType); quint8 c = qBound(0, grad, 255); oLine[x] = qRgba(c, c, c, qAlpha(iLine[x])); } } outImage.save("edge.png"); return EXIT_SUCCESS; }
std::vector<Edgel> EdgelDetector::findEdgelsInRegion(const int left, const int top, const int width, const int height ) { float prev1, prev2; std::vector<Edgel> edgels; // debug function if( drawSectorGrids ) { for( int y=top; y<top+height; y+=RASTERSIZE ) { drawLine( left, y, left+width, y, 128, 128, 128, 1); } for( int x=left; x<left+width; x+=RASTERSIZE ) { drawLine( x, top, x, top+height, 128, 128, 128, 1); } } // debug function if( drawSectors ) { drawLine( left, top, left+width, top, 255, 255, 0, 1); drawLine( left, top, left, top+height, 255, 255, 0, 1); drawLine( left, top+height, left+width, top+height, 255, 255, 0, 1); drawLine( left+width, top, left+width, top+height, 255, 255, 0, 1); } for( int y=0; y<height; y+=RASTERSIZE ) { unsigned char* offset = buffer->getBuffer() + (left + (y+top)*buffer->getWidth() ) * 3; prev1 = prev2 = 0.0f; const int pitch = 3; for( int x=0; x<width; x++) { //// CODE DUPLICATED // check channels int current = edgeKernel( offset, pitch ); if( current > THRESHOLD && edgeKernel( offset+1, pitch ) > THRESHOLD && edgeKernel( offset+2, pitch ) > THRESHOLD ) { // edge! } else { current = 0.0f; } // find local maximum if( prev1 > 0.0f && prev1 > prev2 && prev1 > current ) { Edgel edgel; edgel.setPosition(left+x-1, top+y); edgel.slope = edgeGradientIntensity(edgel.position.x, edgel.position.y); edgels.push_back(edgel); } prev2 = prev1; prev1 = current; offset += pitch; //// CODE DUPLICATED } } // debug function if( drawEdges ) { for( int i=0, s = edgels.size(); i<s; i++ ) { drawPoint( edgels[i].position.x, edgels[i].position.y, 0, 0, 255, THICKNESS); } } int debugNumOfHorizontalEdges = edgels.size(); for( int x=0; x<width; x+=RASTERSIZE ) { unsigned char* offset = buffer->getBuffer() + (left + x + (top*buffer->getWidth() )) * 3; const int pitch = 3*buffer->getWidth(); prev1 = prev2 = 0.0f; for( int y=0; y<height; y++) { //// CODE DUPLICATED // check channels int current = edgeKernel( offset, pitch ); if( current > THRESHOLD && edgeKernel( offset+1, pitch ) > THRESHOLD && edgeKernel( offset+2, pitch ) > THRESHOLD ) { // edge! } else { current = 0.0f; } // find local maximum if( prev1 > 0.0f && prev1 > prev2 && prev1 > current ) { Edgel edgel; edgel.setPosition(left+x, top+y-1); edgel.slope = edgeGradientIntensity(edgel.position.x, edgel.position.y); edgels.push_back(edgel); } prev2 = prev1; prev1 = current; offset += pitch; //// CODE DUPLICATED } } // debug function if( drawEdges ) { for( int i=debugNumOfHorizontalEdges, s = edgels.size(); i<s; i++ ) { drawPoint( edgels[i].position.x, edgels[i].position.y, 0, 255, 0, THICKNESS); } } return edgels; }