图像的边缘检测的原理是检测出图像中所有灰度值变化较大的点,而且这些点连接起来就构成了若干线条,这些线条就可以称为图像的边缘。
直接上代码,函数简介都在代码注释中
//canny边缘检测 -(void)bianyuanjianceImage{ //图像的边缘检测的原理是检测出图像中所有灰度值变化较大的点,而且这些点连接起来就构成了若干线条,这些线条就可以称为图像的边缘。 UIImage *img1 = [UIImage imageNamed:@"1448941176867"]; IplImage *pimage = [self convertToIplImage:img1]; CvSize cvsize; cvsize.width = pimage->width; cvsize.height = pimage->height; //转换为灰度,这里使用Opencv里的颜色空间转换函数cvCvtColor,可以实现RGB颜色向HSV,HSI等颜色空间的转换,也可以转换为灰度图像。 IplImage *huiImage = cvCreateImage(cvsize, pimage->depth,1); cvCvtColor(pimage, huiImage, CV_BGR2GRAY); //边缘检测 float threshold = 50; IplImage *huiImage3 = cvCreateImage(cvsize, huiImage->depth, 1); //canny边缘检测:cvCanny /* void cvCanny( const CvArr* image, CvArr* edges, double threshold1,double threshold2, int aperture_size=3 ); 函数说明: 第一个参数表示输入图像,必须为单通道灰度图。 第二个参数表示输出的边缘图像,为单通道黑白图。 第三个参数和第四个参数表示阈值,这二个阈值中当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割即如果一个像素的梯度大与上限值,则被认为是边缘像素,如果小于下限阈值,则被抛弃。如果该点的梯度在两者之间则当这个点与高于上限值的像素点连接时我们才保留,否则删除。 第五个参数表示Sobel 算子大小,默认为3即表示一个3*3的矩阵。Sobel 算子与高斯拉普拉斯算子都是常用的边缘算子,详细的数学原理可以查阅专业书籍。 */ cvCanny(huiImage, huiImage3, threshold, threshold * 3, 3); //这里多转换了一次,因为UIImage中不能存储纯Gray的图像,将huiImage的内容再转换回IPL_DEPTH_8U色深、3通道图像,虽然下一条语句将原本灰度格式的grayImage转换为BGR格式的grayImagePlus,但那仅仅是格式的转换,灰度图像即使转换成BGR也是没有彩色的,仍然在显示的时候是灰度图像,这么做是为了保证UIImage能够装载而已 IplImage *huiImage33 = cvCreateImage(cvsize, huiImage->depth, 3); cvCvtColor(huiImage3, huiImage33, CV_GRAY2BGR); UIImage *img2 = [self convertToUIImage:huiImage33]; self.imgView.image = img2; cvReleaseImage(&pimage); cvReleaseImage(&huiImage); cvReleaseImage(&huiImage3); cvReleaseImage(&huiImage33); }