【练习6.5】cvSobel及参数要求、cvCartToPolar坐标空间映射、cvMinMaxLoc求自大最小值、cvAvg求平均值
题目要求 |
程序代码 |
结果图片 |
要言妙道 |
创建一副图像,其中只有45度直线,背景为黑色,直线为白色,使用一系列中孔尺寸,得到图像一阶x方向导数核一阶y方向导数,组成图像的输入梯度。使用与cvCartToPolar函数对应的公式测量
优秀代码参考:
1 #include <iostream> 2 #include <cv.h> 3 #include <highgui.h> 4 #include <cxcore.h> 5 6 using namespace std; 7 const CvSize size = cvSize(200,200); 8 const int aperture[] = {3,5,9,11,13,17}; 9 int main() 10 { 11 IplImage *src = cvCreateImage(size,8,1); 12 cvZero(src); 13 cvLine(src 14 //,cvPoint(0,size.height - 1) 15 //,cvPoint(size.width -1 , 0) 16 ,cvPoint(0,0) 17 ,cvPoint(size.width - 1, size.height - 1) 18 ,CV_RGB(255,255,255) 19 ,3 20 ); 21 cvShowImage("src",src); 22 23 IplImage *deriv_x = cvCreateImage(size,IPL_DEPTH_32F,1); 24 IplImage *deriv_y = cvCreateImage(size,IPL_DEPTH_32F,1); 25 IplImage *magnitude = cvCreateImage(size,IPL_DEPTH_32F,1); 26 IplImage *angle = cvCreateImage(size,IPL_DEPTH_32F,1); 27 IplImage *mask = cvCreateImage(size,IPL_DEPTH_8U,1); 28 for(int i=0;i<sizeof(aperture)/sizeof(aperture[0]);++i){ 29 cvSobel(src,deriv_x,1,0,aperture[i]); 30 cvSobel(src,deriv_y,0,1,aperture[i]); 31 32 cvCartToPolar(deriv_x,deriv_y,magnitude,angle,1); 33 34 cvSave("x.xml",deriv_x); 35 cvSave("y.xml",deriv_y); 36 cvSave("magnitude.xml",magnitude); 37 cvSave("angle.xml",angle); 38 39 double max_mag ,min_mag ,max_angle , min_angle; 40 cvMinMaxLoc(magnitude,&min_mag,&max_mag); 41 cvMinMaxLoc(angle,&min_angle,&max_angle); 42 cout<<"magnitude: max = "<<max_mag<<" min = "<<min_mag<<endl; 43 cout<<"angle : max = "<<max_angle<<" min = "<<min_angle<<endl; 44 45 cvCmpS(magnitude,max_mag*3/4,mask,CV_CMP_GT); 46 cvShowImage("mask",mask); 47 48 CvScalar scalar = cvAvg(angle,mask); 49 cout<<"aperture = "<<aperture[i]<<", line angle = "<<scalar.val[0]<<endl; 50 cvWaitKey(); 51 } 52 cvReleaseImage(&src); 53 cvReleaseImage(&magnitude); 54 cvReleaseImage(&angle); 55 cvReleaseImage(&mask); 56 cvDestroyAllWindows(); 57 58 }
源自:学习opencv第六章习题5 , 使用x,y阶层数求出图像内唯一直线的角度
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 const CvSize size = cvSize(400, 400); 25 const int aperture[] = { 1, 3, 5, 7 }; 26 27 cvNamedWindow("原始图像", CV_WINDOW_AUTOSIZE); 28 IplImage * image_Gray = cvCreateImage(size, IPL_DEPTH_8U, 1); 29 cvZero(image_Gray); 30 31 //画5度直线 32 cvLine(image_Gray, cvPoint(0, 0), cvPoint(size.width, size.height), cvScalar(255), 3); 33 34 cvShowImage("原始图像", image_Gray); 35 36 IplImage *deriv_x = cvCreateImage(size, IPL_DEPTH_32F, 1); 37 IplImage *deriv_y = cvCreateImage(size, IPL_DEPTH_32F, 1); 38 IplImage *magnitude = cvCreateImage(size, IPL_DEPTH_32F, 1); 39 IplImage *angle = cvCreateImage(size, IPL_DEPTH_32F, 1); 40 IplImage *mask = cvCreateImage(size, IPL_DEPTH_8U, 1); 41 42 //求导 43 int filtersNum = sizeof(aperture) / sizeof(aperture[0]); for (int i = 0; i<filtersNum; ++i) 44 { 45 cvSobel(image_Gray, deriv_x, 1, 0, aperture[i]); 46 cvSobel(image_Gray, deriv_y, 0, 1, aperture[i]); 47 48 cvCartToPolar(deriv_x, deriv_y, magnitude, angle, 1); 49 50 cvSave("x.xml", deriv_x); 51 cvSave("y.xml", deriv_y); 52 cvSave("magnitude.xml", magnitude); 53 cvSave("angle.xml", angle); 54 55 double max_mag, min_mag, max_angle, min_angle; 56 cvMinMaxLoc(magnitude, &min_mag, &max_mag); 57 cvMinMaxLoc(angle, &min_angle, &max_angle); 58 cout << "magnitude: max = " << max_mag << " min = " << min_mag << endl; 59 cout << "angle : max = " << max_angle << " min = " << min_angle << endl; 60 61 cvCmpS(magnitude, max_mag * 3 / 4, mask, CV_CMP_GT); 62 63 //窗口名称及显示 64 char *pre_mask = "ApertureFilter_mask:"; 65 char *aperature_size = new char(1); 66 _itoa_s(aperture[i], aperature_size, 2, 10); 67 int name_size = strlen(pre_mask) + strlen(aperature_size) + 1; 68 char * windowName_mask = new char(name_size); 69 strcpy_s(windowName_mask, name_size, pre_mask); 70 strcat_s(windowName_mask, name_size, aperature_size); 71 72 cvShowImage(windowName_mask, mask); 73 74 CvScalar scalar = cvAvg(angle, mask); 75 cout << "aperture = " << aperture[i] << ", line angle = " << scalar.val[0] << endl; 76 } 77 78 cvWaitKey(); 79 80 cvReleaseImage(&image_Gray); 81 cvReleaseImage(&magnitude); 82 cvReleaseImage(&angle); 83 cvReleaseImage(&mask); 84 cvDestroyAllWindows(); 85 86 return 0; 87 }
①cvSobel支持(aperture_size = 1,3,5,7) or Scharr (aperture_size = -1) operator,所以,没有安装题目中要求使用9×9滤波器完成
②可以使用cvShowImage显示deriv_x等所有图像,但必须使用cvConvertScale 或 cvConvertScaleAbs转换为8为才能看到正确的图像,代码中使用cvSave保存到了文件中,更容易观察
③cvCartToPolar函数正是使用了题目中的公式来计算magnitude及 angle,相见OpenCV参考
④cvSobel执行时,如果输入图像为8位,输出图像必须≥IPL_DEPTH_16S,《学习OpenCV》中文英版说图像深度必须是IPL_DEPTH_16S应该不准确
‖==========钟于原创 乐于分享 宁静致远 毋忆典藏==========‖