【练习6.8】霍夫直线变换、圆变换,cvCanny边缘检测,找圆找直线
题目要求 |
程序代码 |
结果图片 |
要言妙道 |
使用霍夫直线变换和霍夫圆变换
a、找圆
b、找直线
1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点。 2 // 3 //D:\\Work\\Work_Programming\\Source\\Image\\lena.jpg 4 5 6 #include "stdafx.h" 7 #include <cv.h> 8 #include <highgui.h> 9 #include <iostream> 10 11 #include <opencv2/legacy/legacy.hpp> 12 //#pragma comment(lib, "opencv_legacy2411.lib") 13 14 using namespace cv; 15 using namespace std; 16 17 //函数声明-->--->-->--->-->--->-->--->// 18 19 20 //<--<--<--<--<--<--<--<--<--函数声明// 21 22 int _tmain(int argc, _TCHAR* argv[]) 23 { 24 char * soutceFile = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第6章\\奥运五环2.jpg"; 25 IplImage * image_Resource = cvLoadImage(soutceFile, CV_LOAD_IMAGE_GRAYSCALE); 26 assert(image_Resource); 27 28 cvNamedWindow("原始图像", CV_WINDOW_AUTOSIZE); 29 cvNamedWindow("题目_a", CV_WINDOW_AUTOSIZE); 30 cvNamedWindow("题目_b", CV_WINDOW_AUTOSIZE); 31 32 cvShowImage("原始图像", image_Resource); 33 34 //---------------------------a:开始--------------------------------// 35 36 IplImage * image_Result_a = cvCloneImage(image_Resource); 37 //cvZero(image_Result_a); 38 39 CvMemStorage* storage = cvCreateMemStorage(0); 40 CvSeq* results = cvHoughCircles( 41 image_Result_a, 42 storage, 43 CV_HOUGH_GRADIENT, 44 1, 45 image_Result_a->width / 10, 46 200 47 ); 48 49 for (int i = 0; i < results->total; i++) 50 { 51 float* p = (float*)cvGetSeqElem(results, i); 52 CvPoint pt = cvPoint(cvRound(p[0]), cvRound(p[1])); 53 cvCircle( 54 image_Result_a, 55 pt, 56 cvRound(p[2]), 57 CV_RGB(0xff, 0xff, 0xff) 58 ); 59 } 60 61 cvShowImage("题目_a", image_Result_a); 62 63 //---------------------------a:结束--------------------------------// 64 65 //---------------------------b:开始--------------------------------// 66 67 soutceFile = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第6章\\窗.jpg"; 68 image_Resource = cvLoadImage(soutceFile, CV_LOAD_IMAGE_UNCHANGED); 69 assert(image_Resource); 70 71 int i; 72 IplImage* dst = cvCreateImage(cvGetSize(image_Resource), 8, 1); 73 IplImage* color_dst = cvCreateImage(cvGetSize(image_Resource), 8, 3); 74 CvMemStorage* storage2 = cvCreateMemStorage(0); 75 CvSeq* lines = 0; 76 77 IplImage* src1 = cvCreateImage(cvSize(image_Resource->width, image_Resource->height), IPL_DEPTH_8U, 1); 78 cvCvtColor(image_Resource, src1, CV_BGR2GRAY); 79 cvCanny(src1, dst, 50, 200, 3); 80 cvCvtColor(dst, color_dst, CV_GRAY2BGR); 81 82 lines = cvHoughLines2(dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI / 180, 80, 30, 10); 83 for (i = 0; i < lines->total; i++) 84 { 85 CvPoint* line = (CvPoint*)cvGetSeqElem(lines, i); 86 cvLine(color_dst, line[0], line[1], CV_RGB(255, 0, 0), 2, 8); 87 } 88 89 cvNamedWindow("Source", CV_WINDOW_NORMAL); 90 cvShowImage("Source", image_Resource); 91 cvNamedWindow("Hough", CV_WINDOW_NORMAL); 92 cvShowImage("Hough", color_dst); 93 94 //---------------------------b:结束--------------------------------// 95 96 cvWaitKey(0); 97 98 cvReleaseImage(&image_Resource); 99 cvReleaseImage(&image_Result_a); 100 //cvReleaseImage(&image_Result_b); 101 102 cvDestroyAllWindows(); 103 104 return 0; 105 }
优秀代码参考:
1 #include <cv.h> 2 #include <highgui.h> 3 #include <math.h> 4 int main(int argc, char** argv) 5 { 6 IplImage* img; 7 if( argc == 2 && (img=cvLoadImage(argv[1], 1))!= 0) 8 { 9 IplImage* gray = cvCreateImage( cvGetSize(img), 8, 1 ); 10 CvMemStorage* storage = cvCreateMemStorage(0); 11 cvCvtColor( img, gray, CV_BGR2GRAY ); 12 cvSmooth( gray, gray, CV_GAUSSIAN, 9, 9 ); // smooth it, otherwise a lot of false circles may be 13 detected 14 CvSeq* circles = cvHoughCircles( gray, storage, CV_HOUGH_GRADIENT, 2, gray->height/4, 200, 100 ); 15 int i; 16 for( i = 0; i < circles->total; i++ ) 17 { 18 float* p = (float*)cvGetSeqElem( circles, i ); 19 cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 3, CV_RGB(0,255,0), -1, 8, 0 ); 20 cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,0,0), 3, 8, 0 ); 21 } 22 cvNamedWindow( "circles", 1 ); 23 cvShowImage( "circles", img ); 24 } 25 return 0; 26 }
1 /* This is a standalone program. Pass an image name as a first parameter 2 of the program.Switch between standard and probabilistic Hough transform 3 by changing "#if 1" to "#if 0" and back */ 4 #include <cv.h> 5 #include <highgui.h> 6 #include <math.h> 7 int main(int argc, char** argv) 8 { 9 IplImage* src; 10 if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0) 11 { 12 IplImage* dst = cvCreateImage( cvGetSize(src), 8, 1 ); 13 IplImage* color_dst = cvCreateImage( cvGetSize(src), 8, 3 ); 14 CvMemStorage* storage = cvCreateMemStorage(0); 15 CvSeq* lines = 0; 16 int i; 17 IplImage* src1=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1); 18 cvCvtColor(src, src1, CV_BGR2GRAY); 19 cvCanny( src1, dst, 50, 200, 3 ); 20 cvCvtColor( dst, color_dst, CV_GRAY2BGR ); 21 #if 1 22 lines = cvHoughLines2( dst, storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 150, 0, 0 ); 23 for( i = 0; i < lines->total; i++ ) 24 { 25 float* line = (float*)cvGetSeqElem(lines,i); 26 float rho = line[0]; 27 float theta = line[1]; 28 CvPoint pt1, pt2; 29 double a = cos(theta), b = sin(theta); 30 if( fabs(a) < 0.001 ) 31 { 32 pt1.x = pt2.x = cvRound(rho); 33 pt1.y = 0; 34 pt2.y = color_dst->height; 35 } 36 else if( fabs(b) < 0.001 ) 37 { 38 pt1.y = pt2.y = cvRound(rho); 39 pt1.x = 0; 40 pt2.x = color_dst->width; 41 } 42 else 43 { 44 pt1.x = 0; 45 pt1.y = cvRound(rho/b); 46 pt2.x = cvRound(rho/a); 47 pt2.y = 0; 48 } 49 cvLine( color_dst, pt1, pt2, CV_RGB(255,0,0), 3, 8 ); 50 } 51 #else 52 lines = cvHoughLines2( dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 80, 30, 10 ); 53 for( i = 0; i < lines->total; i++ ) 54 { 55 CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i); 56 cvLine( color_dst, line[0], line[1], CV_RGB(255,0,0), 3, 8 ); 57 } 58 #endif 59 cvNamedWindow( "Source", 1 ); 60 cvShowImage( "Source", src ); 61 cvNamedWindow( "Hough", 1 ); 62 cvShowImage( "Hough", color_dst ); 63 cvWaitKey(0); 64 }
①使用cvHoughCircles前注意对图像适当的处理,例如:cvSmooth
②使用cvHoughLines2前注意使用cvCanny
③注意cvHoughLines2的另两种method,CV_HOUGH_STANDARD,CV_HOUTH_MULTI_SCALE及各自的用法及参数意义
‖==========钟于原创 乐于分享 宁静致远 毋忆典藏==========‖