void Image::setNumCorners() { memset(numCorners,0,sizeof(double)*NUM); Mat *dst,*dstnorm; dst = new Mat(); dstnorm = new Mat(); int blockSize = 2; int apertureSize = 3; double k = 0.04; int thresh = 200; for(int t=0;t<NUM;t++) { readInGray(t); cornerHarris(*gray,*dst,blockSize,apertureSize,k,BORDER_DEFAULT); // normalizing normalize(*dst,*dstnorm,0,255,NORM_MINMAX,CV_32FC1,Mat()); // count corners for(int i=0;i<dstnorm->rows;i++) for(int j=0;j<dstnorm->cols;j++) if((int) dstnorm->at<float>(i,j) >thresh) numCorners[t]++; delete gray; //cout<<numCorners[t]<<endl; } delete dst; delete dstnorm; cout<<"corner...ok"<<endl; }
// Harris points vector<Point> harris(const Image<float>& I, double th,int n) { vector<Point> v; Image<float> H; cornerHarris(I,H,10,3,0.04); for (int y=n;y<I.height()-n;y++) for (int x=n;x<I.width()-n;x++) if (H(x,y) > th && H(x,y)>H(x,y+1) && H(x,y)>H(x,y-1) && H(x,y)>H(x-1,y-1) && H(x,y)>H(x-1,y) && H(x,y)>H(x-1,y+1) && H(x,y)>H(x+1,y-1) && H(x,y)>H(x+1,y) && H(x,y)>H(x+1,y+1)) v.push_back(Point(x,y)); return v; }
KDvoid CornerHarris ( KDint nIdx ) { Mat tSrc; Mat tGray; KDint nThresh; nThresh = 205; // Load source image and convert it to gray tSrc = imread ( "/res/image/building.png" ); cvtColor ( tSrc, tGray, CV_BGR2GRAY ); // // Executes the corner detection and draw a circle around the possible corners // Mat tCorner; Mat tNorm; Mat tNormScaled; // Detector parameters KDint nBlockSize = 2; KDint nApertureSize = 3; KDdouble dK = 0.04; tCorner = Mat::zeros ( tSrc.size ( ), CV_32FC1 ); // Detecting corners cornerHarris ( tGray, tCorner, nBlockSize, nApertureSize, dK, BORDER_DEFAULT ); // Normalizing normalize ( tCorner, tNorm, 0, 255, NORM_MINMAX, CV_32FC1, Mat ( ) ); convertScaleAbs ( tNorm, tNormScaled ); // Drawing a circle around corners for ( KDint j = 0; j < tNorm.rows ; j++ ) { for ( KDint i = 0; i < tNorm.cols; i++ ) { if( (KDint) tNorm.at<KDfloat> ( j, i ) > nThresh ) { circle ( tNormScaled, Point ( i, j ), 5, Scalar ( 0 ), 2, 8, 0 ); } } } g_pController->setFrame ( 1, tSrc ); g_pController->setFrame ( 2, tNormScaled ); }
void harris(int thresh, Mat img, char *window_name, char *filename) { cout << filename << endl; char *filename_cornerless = "harris_cornerless.jpg", *filename_final = "harris_final.jpg"; Mat dst, dst_norm, dst_norm_scaled; Mat img_gray; cvtColor(img, img_gray, CV_BGR2GRAY); DWORD t1, t2, t; dst = Mat::zeros(img.size(), CV_32FC1); /// Detector parameters int blockSize = 2; int count = 0; int apertureSize = 3; double k = 0.04; /// Detecting corners t1 = ticks; cornerHarris(img_gray, dst, blockSize, apertureSize, k, BORDER_DEFAULT); t2 = ticks; t = t2 - t1; /// Normalizing normalize(dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat()); convertScaleAbs(dst_norm, dst_norm_scaled); imwrite(filename_cornerless, dst_norm_scaled); /// Drawing a circle around corners for(int j = 0; j < dst_norm.rows ; j++) { for(int i = 0; i < dst_norm.cols; i++) { if((int) dst_norm.at<float>(j,i) > thresh) { circle(img, Point(i, j), 5, Scalar(0, 0, 255), 1, 8, 0); count++; } } } /// Showing the result cout << "Harris features detected: " << count << endl << "Time to execute: " << t << endl; imwrite(filename, img); namedWindow(window_name, CV_WINDOW_AUTOSIZE); imshow(window_name, img); }
ToolsMenu::ToolsMenu(ImageViewer* iv, QWidget* parent) : QWidget(parent), ui(new Ui::ToolsMenu) { ui->setupUi(this); setLayout(ui->verticalLayoutWidget->layout()); m_viewer = (ImageViewer*) iv; m_tools = new Tools(m_viewer, this); // locking tools menu when performing transformation connect(m_viewer, SIGNAL(lockTools()), this, SLOT(disableAllTools())); connect(m_viewer, SIGNAL(unlockTools()), this, SLOT(enableAllTools())); /* ------------------------------------------------------- * ROTATION * ------------------------------------------------------- */ connect(ui->rotate90Button, SIGNAL(clicked()), m_tools, SLOT(rotate90())); connect(ui->rotate180Button, SIGNAL(clicked()), m_tools, SLOT(rotate180())); connect(ui->rotate270Button, SIGNAL(clicked()), m_tools, SLOT(rotate270())); /* ------------------------------------------------------- * HISTOGRAM * ------------------------------------------------------- */ QMenu* hMenu = new QMenu(ui->histogramButton); hMenu->addAction( QIcon(":/icons/icons/chart_curve_error.png"), QString("Equalize histograms"), m_tools, SLOT(histogramEqualize()) ); hMenu->addAction( QIcon(":/icons/icons/chart_curve_go.png"), QString("Stretch histograms"), m_tools, SLOT(histogramStretch()) ); ui->histogramButton->setMenu(hMenu); /* ------------------------------------------------------- * FILTERS (convolution, blur) * ------------------------------------------------------- */ QMenu* bMenu = new QMenu(ui->blurButton); bMenu->addAction( QIcon(":/icons/icons/draw_convolve.png"), QString("Gaussian blur"), m_tools, SLOT(blurGauss()) ); bMenu->addAction( QIcon(":/icons/icons/draw_convolve.png"), QString("Uniform blur"), m_tools, SLOT(blurUniform()) ); bMenu->addAction( QIcon(":/icons/icons/flag_airfield_vehicle_safety.png"), QString("Custom linear filter"), m_tools, SLOT(blurLinear()) ); ui->blurButton->setMenu(bMenu); /* ------------------------------------------------------- * BINARIZATION * ------------------------------------------------------- */ QMenu* binMenu = new QMenu(ui->binarizationButton); binMenu->addAction( QIcon(":/icons/icons/universal_binary.png"), QString("Manual"), m_tools, SLOT(binManual()) ); binMenu->addAction( QIcon(":/icons/icons/universal_binary.png"), QString("Gradient"), m_tools, SLOT(binGradient()) ); binMenu->addAction( QIcon(":/icons/icons/universal_binary.png"), QString("Iterative bimodal"), m_tools, SLOT(binIterBimodal()) ); binMenu->addAction( QIcon(":/icons/icons/universal_binary.png"), QString("Niblack"), m_tools, SLOT(binNiblack()) ); binMenu->addAction( QIcon(":/icons/icons/universal_binary.png"), QString("Otsu"), m_tools, SLOT(binOtsu()) ); ui->binarizationButton->setMenu(binMenu); /* ------------------------------------------------------- * NOISE REDUCTION * ------------------------------------------------------- */ QMenu* nMenu = new QMenu(ui->noiseButton); nMenu->addAction( QIcon(":/icons/icons/checkerboard.png"), QString("Median"), m_tools, SLOT(noiseMedian()) ); nMenu->addAction( QIcon(":/icons/icons/checkerboard.png"), QString("Bilateral"), m_tools, SLOT(noiseBilateral()) ); ui->noiseButton->setMenu(nMenu); /* ------------------------------------------------------- * MORPHOLOGICAL * ------------------------------------------------------- */ QMenu* morphMenu = new QMenu(ui->morphButton); morphMenu->addAction( QIcon(":/icons/icons/arrow_out.png"), QString("Dilate"), m_tools, SLOT(morphDilate()) ); morphMenu->addAction( QIcon(":/icons/icons/arrow_in.png"), QString("Erode"), m_tools, SLOT(morphErode()) ); morphMenu->addAction( QIcon(":/icons/icons/arrow_divide.png"), QString("Open"), m_tools, SLOT(morphOpen()) ); morphMenu->addAction( QIcon(":/icons/icons/arrow_join.png"), QString("Close"), m_tools, SLOT(morphClose()) ); ui->morphButton->setMenu(morphMenu); /* ------------------------------------------------------- * EDGE DETECTION * ------------------------------------------------------- */ QMenu* eMenu = new QMenu(ui->edgeButton); eMenu->addAction( QIcon(":/icons/icons/key_s.png"), QString("Sobel"), m_tools, SLOT(edgeSobel()) ); eMenu->addAction( QIcon(":/icons/icons/key_p.png"), QString("Prewitt"), m_tools, SLOT(edgePrewitt()) ); eMenu->addAction( QIcon(":/icons/icons/key_r.png"), QString("Roberts"), m_tools, SLOT(edgeRoberts()) ); eMenu->addAction( QIcon(":/icons/icons/edge_detection.png"), QString("Laplacian"), m_tools, SLOT(edgeLaplacian()) ); eMenu->addAction( QIcon(":/icons/icons/edge_detection.png"), QString("Zero-crossing (LoG)"), m_tools, SLOT(edgeZero()) ); eMenu->addAction( QIcon(":/icons/icons/edge_detection.png"), QString("Canny"), m_tools, SLOT(edgeCanny()) ); ui->edgeButton->setMenu(eMenu); /* ------------------------------------------------------- * TEXTURES * ------------------------------------------------------- */ QMenu* texMenu = new QMenu(ui->textureButton); texMenu->addAction( QIcon(":/icons/icons/flag_airfield_vehicle_safety.png"), QString("Height map"), m_tools, SLOT(mapHeight()) ); texMenu->addAction( QIcon(":/icons/icons/flag_airfield_vehicle_safety.png"), QString("Normal map"), m_tools, SLOT(mapNormal()) ); texMenu->addAction( QIcon(":/icons/icons/flag_airfield_vehicle_safety.png"), QString("Horizon map"), m_tools, SLOT(mapHorizon()) ); ui->textureButton->setMenu(texMenu); /* ------------------------------------------------------- * TRANSFORMATIONS * ------------------------------------------------------- */ QMenu* transMenu = new QMenu(ui->transformationsButton); transMenu->addAction( QIcon(":/icons/icons/videodisplay.png"), QString("Hough"), m_tools, SLOT(houghTransform()) ); transMenu->addAction( QIcon(":/icons/icons/videodisplay.png"), QString("Hough - lines"), m_tools, SLOT(houghLines()) ); transMenu->addAction( QIcon(":/icons/icons/videodisplay.png"), QString("Hough - rectangles"), m_tools, SLOT(houghRectangles()) ); transMenu->addAction( QIcon(":/icons/icons/videodisplay.png"), QString("Segmentation"), m_tools, SLOT(segmentation()) ); ui->transformationsButton->setMenu(transMenu); /* ------------------------------------------------------- * CORNER DETECTION * ------------------------------------------------------- */ QMenu* cornerMenu = new QMenu(ui->cornerButton); cornerMenu->addAction( QIcon(":/icons/icons/things_digital.png"), QString("Harris"), m_tools, SLOT(cornerHarris()) ); ui->cornerButton->setMenu(cornerMenu); }
void goodFeaturesToTrack( const Mat& image, vector<Point2f>& corners, int maxCorners, double qualityLevel, double minDistance, const Mat& mask, int blockSize, bool useHarrisDetector, double harrisK ) { CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 ); if( mask.data ) CV_Assert( mask.type() == CV_8UC1 && mask.size() == image.size() ); Mat eig, tmp; if( useHarrisDetector ) cornerHarris( image, eig, blockSize, 3, harrisK ); else cornerMinEigenVal( image, eig, blockSize, 3 ); double maxVal = 0; minMaxLoc( eig, 0, &maxVal, 0, 0, mask ); threshold( eig, eig, maxVal*qualityLevel, 0, THRESH_TOZERO ); dilate( eig, tmp, Mat()); Size imgsize = image.size(); vector<const float*> tmpCorners; // collect list of pointers to features - put them into temporary image for( int y = 1; y < imgsize.height - 1; y++ ) { const float* eig_data = (const float*)eig.ptr(y); const float* tmp_data = (const float*)tmp.ptr(y); const uchar* mask_data = mask.data ? mask.ptr(y) : 0; for( int x = 1; x < imgsize.width - 1; x++ ) { float val = eig_data[x]; if( val != 0 && val == tmp_data[x] && (!mask_data || mask_data[x]) ) tmpCorners.push_back(eig_data + x); } } sort( tmpCorners, greaterThanPtr<float>() ); corners.clear(); size_t i, j, total = tmpCorners.size(), ncorners = 0; if(minDistance >= 1) { // Partition the image into larger grids int w = image.cols; int h = image.rows; const int cell_size = (int)(minDistance); const int grid_width = (float)w / cell_size + 0.5; // round up const int grid_height = (float)h / cell_size + 0.5; // round up std::vector < std::vector <Point2f> > grid(grid_width*grid_height); minDistance *= minDistance; for( i = 0; i < total; i++ ) { int ofs = (int)((const uchar*)tmpCorners[i] - eig.data); int y = (int)(ofs / eig.step); int x = (int)((ofs - y*eig.step)/sizeof(float)); bool good = true; int x_cell = x / cell_size; int y_cell = y / cell_size; int x1 = x_cell - 1; int y1 = y_cell - 1; int x2 = x_cell + 1; int y2 = y_cell + 1; // boundary check x1 = std::max(0, x1); y1 = std::max(0, y1); x2 = std::min(grid_width-1, x2); y2 = std::min(grid_height-1, y2); for( int yy = y1; yy <= y2; yy++ ) { for( int xx = x1; xx <= x2; xx++ ) { vector <Point2f> &m = grid[yy*grid_width + xx]; if( m.size() ) { for(j = 0; j < m.size(); j++) { float dx = x - m[j].x; float dy = y - m[j].y; if( dx*dx + dy*dy < minDistance ) { good = false; goto break_out; } } } } } break_out: if(good) { // printf("%d: %d %d -> %d %d, %d, %d -- %d %d %d %d, %d %d, c=%d\n", // i,x, y, x_cell, y_cell, (int)minDistance, cell_size,x1,y1,x2,y2, grid_width,grid_height,c); grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y)); corners.push_back(Point2f((float)x, (float)y)); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) break; } } } else { for( i = 0; i < total; i++ ) { int ofs = (int)((const uchar*)tmpCorners[i] - eig.data); int y = (int)(ofs / eig.step); int x = (int)((ofs - y*eig.step)/sizeof(float)); corners.push_back(Point2f((float)x, (float)y)); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) break; } } /* for( i = 0; i < total; i++ ) { int ofs = (int)((const uchar*)tmpCorners[i] - eig.data); int y = (int)(ofs / eig.step); int x = (int)((ofs - y*eig.step)/sizeof(float)); if( minDistance > 0 ) { for( j = 0; j < ncorners; j++ ) { float dx = x - corners[j].x; float dy = y - corners[j].y; if( dx*dx + dy*dy < minDistance ) break; } if( j < ncorners ) continue; } corners.push_back(Point2f((float)x, (float)y)); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) break; } */ }
void harris_detection(Mat &image,double threshold_value){ /* Mat dst, dst_norm, dst_norm_scaled; dst = Mat::zeros( image.size(), CV_32FC1 ); int blockSize = 2; int apertureSize = 3; double k = 0.01; int thresh = 100; int max_thresh = 255; /// Detecting corners cornerHarris( image, dst, blockSize, apertureSize, k ); imwrite("outimage/dst.png",dst); /// Normalizing normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() ); convertScaleAbs( dst_norm, dst_norm_scaled ); /// Drawing a circle around corners for( int j = 0; j < dst_norm.rows ; j++ ) { for( int i = 0; i < dst_norm.cols; i++ ) { if( (int) dst_norm.at<float>(j,i) > thresh ) { circle( dst_norm_scaled, Point( i, j ), 5, Scalar(0), 2, 8, 0 ); } } } imwrite("outimage/dst_norm_scaled.png",dst_norm_scaled); */ int blockSize = 3; int apertureSize = 3; double k = 0.001; Mat cornerStrength; cornerHarris(image,cornerStrength,blockSize, apertureSize, k); threshold(cornerStrength,cornerStrength,threshold_value,255,THRESH_BINARY); imwrite("outimage/cornerStrength.png",cornerStrength); double maxStrength; double minStrength; minMaxLoc(cornerStrength,&minStrength,&maxStrength); Mat dilated; Mat locaMax; dilate(cornerStrength,dilated,Mat()); compare(cornerStrength,dilated,locaMax,CMP_EQ); Mat cornerMap; double qualityLevel=0.01; double th=qualityLevel*maxStrength; threshold(cornerStrength,cornerMap,th,255,THRESH_BINARY); cornerMap.convertTo(cornerMap,CV_8U); bitwise_and(cornerMap,locaMax,cornerMap); drawCornerOnImage(image,cornerMap); imwrite("outimage/harris_image.png",cornerMap); }
/* Point2f Recognition::RefineCornerPosition(Mat& img, Point2f ROICenter, vector<Point2f> refinedSquares){ vector<Point2f> refinedCorners; //check if point to be refined is in an occluded part or there is a corner close!! unsigned int i= 0; bool found= false; while(i< refinedSquares.size() && !found){ if(norm(ROICenter - refinedSquares[i]) < projectedSquareSize) found= true; i++; } //if found is true, there should be a corner any close and we refine the coordinates of it if(found){ Mat srcGray; cvtColor(img, srcGray, CV_BGR2GRAY); Mat mask = Mat::zeros(img.size(), CV_8UC1); int edgeLenght= projectedSquareSize-5; int leftBoundX; int rightBoundX; int upperBoundY; int lowerBoundY; if((ROICenter.x- edgeLenght/2)< 0) leftBoundX= 0; else leftBoundX= ROICenter.x- edgeLenght/2; if((ROICenter.x+ edgeLenght/2)> img.cols) rightBoundX= img.cols; else rightBoundX= ROICenter.x+ edgeLenght/2; if((ROICenter.y- edgeLenght/2)< 0) upperBoundY= 0; else upperBoundY= ROICenter.y- edgeLenght/2; if((ROICenter.y+ edgeLenght/2)> img.rows) lowerBoundY= img.rows; else lowerBoundY= ROICenter.y+ edgeLenght/2; // set region of interest for (int i= leftBoundX ; i< rightBoundX; i++){ for (int j= upperBoundY ; j< lowerBoundY; j++){ mask.row(j).col(i) = 1; } } cornerHarris(img, OutputArray dst, int blockSize, int ksize, double k, int borderType=BORDER_DEFAULT ) goodFeaturesToTrack(srcGray, refinedCorners, 1, .1, 0.2, mask); } if(refinedCorners.empty()) return ROICenter; else return refinedCorners[0]; } */ vector<Point2f> Recognition::RefineCornerPositions(Mat& img, vector<Point2f> ROICenters, vector<Point2f> refinedSquares, int horizontalSize){ Mat srcGray; Mat refinedCorners, refinedCorners_norm, refinedCorners_norm_scaled; vector<Point2f> finalMesh; int edgeLenght= projectedSquareSize-5; cvtColor(img, srcGray, CV_BGR2GRAY); cornerHarris(srcGray, refinedCorners, 2, 3, .04, BORDER_DEFAULT); normalize( refinedCorners, refinedCorners_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() ); convertScaleAbs( refinedCorners_norm, refinedCorners_norm_scaled ); for(unsigned int i=0; i< ROICenters.size(); i++){ int leftBoundX, rightBoundX, upperBoundY, lowerBoundY; if((ROICenters[i].x- edgeLenght/2)< 0) leftBoundX= 0; else leftBoundX= ROICenters[i].x- edgeLenght/2; if((ROICenters[i].x+ edgeLenght/2)> img.cols) rightBoundX= img.cols; else rightBoundX= ROICenters[i].x+ edgeLenght/2; if((ROICenters[i].y- edgeLenght/2)< 0) upperBoundY= 0; else upperBoundY= ROICenters[i].y- edgeLenght/2; if((ROICenters[i].y+ edgeLenght/2)> img.rows) lowerBoundY= img.rows; else lowerBoundY= ROICenters[i].y+ edgeLenght/2; Point2f maxCorner(0,0); for(int j=upperBoundY; j< lowerBoundY; j++){ for(int k=leftBoundX; k< rightBoundX; k++){ if( refinedCorners_norm.at<float>(j,k) > refinedCorners_norm.at<float>(maxCorner.y, maxCorner.x)){ maxCorner.y= j; maxCorner.x= k; } } } //check if there is a square any close and return true if so unsigned int s= 0; bool found= false; while(s< refinedSquares.size() && !found){ if(norm(ROICenters[i] - refinedSquares[s]) < projectedSquareSize*0.2) found= true; s++; } if(maxCorner.x!=0 && maxCorner.y!=0 && found){ if(i==0) finalMesh.push_back(maxCorner); else if(i%(horizontalSize+1)== 0){ if(fabs(finalMesh[i-(horizontalSize+1)].y - maxCorner.y) < 1.2*projectedSquareSize && fabs(finalMesh[i-(horizontalSize+1)].y - maxCorner.y)> .8*projectedSquareSize && maxCorner.x< 1.2* finalMesh[i-(horizontalSize+1)].x && maxCorner.x> .8* finalMesh[i-(horizontalSize+1)].x) finalMesh.push_back(maxCorner); else finalMesh.push_back(Point2f(finalMesh[i-(horizontalSize+1)].x, finalMesh[i-(horizontalSize+1)].y+ projectedSquareSize)); } else if(fabs(finalMesh[i-1].x - maxCorner.x) < 1.2*projectedSquareSize && fabs(finalMesh[i-1].x - maxCorner.x)> .8*projectedSquareSize && maxCorner.y< 1.2* finalMesh[i-1].y && maxCorner.y> .8* finalMesh[i-1].y) finalMesh.push_back(maxCorner); else finalMesh.push_back(Point2f(finalMesh[i-1].x + projectedSquareSize, finalMesh[i-1].y)); } else{ if(i==0) finalMesh.push_back(ROICenters[i]); else if(i%(horizontalSize+1)== 0) finalMesh.push_back(Point2f(finalMesh[i-(horizontalSize+1)].x, finalMesh[i-(horizontalSize+1)].y+ projectedSquareSize)); else finalMesh.push_back(Point2f(finalMesh[i-1].x + projectedSquareSize, finalMesh[i-1].y)); //finalMesh.push_back(ROICenters[i]); } } return finalMesh; }