实现图像边缘的算法的思路是:首先将图像转换为二值图像,然后膨胀此二值图像,最后减去未膨胀之前的图像便得到了图像的边缘。
参考代码如下所示:
int _tmain(int argc, _TCHAR* argv[]) { IplImage *srcImg = cvLoadImage("test.jpg"); IplImage *grayImg = cvCreateImage(cvGetSize(srcImg), 8, 1); cvCvtColor(srcImg, grayImg, CV_BGR2GRAY); IplImage *dstImg = cvCreateImage(cvGetSize(srcImg), 8, 1); cvThreshold(grayImg, dstImg, cv::Otsu(srcImg), 255, CV_THRESH_BINARY); IplConvKernel *kernel = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_CROSS); cvMorphologyEx(dstImg, dstImg, NULL, kernel, CV_MOP_OPEN, 3); cvMorphologyEx(dstImg, dstImg, NULL, kernel, CV_MOP_CLOSE, 1); // Find edges: dilate(image) - image; IplImage *dilatedImg = cvCreateImage(cvGetSize(srcImg), 8, 1); cvDilate(dstImg, dilatedImg, kernel, 1); cvSub(dilatedImg, dstImg, dstImg); // Label edges in srcImg IplImage *redCh = cvCreateImage(cvGetSize(srcImg), 8, 1); IplImage *greenCh = cvCreateImage(cvGetSize(srcImg), 8, 1); IplImage *blueCh = cvCreateImage(cvGetSize(srcImg), 8, 1); cvSplit(srcImg, blueCh, greenCh, redCh, NULL); cvOr(redCh, dstImg, redCh); cvMerge(blueCh, greenCh, redCh, NULL, srcImg); cvNamedWindow("src"); cvShowImage("src", srcImg); cvNamedWindow("dst"); cvShowImage("dst", dstImg); cvWaitKey(0); return 0; }其中cv::Otsu(srcImg)的算法,可参考http://en.wikipedia.org/wiki/Otsu%27s_method
输出结果:
关于Image Engineering & Computer Vision的更多讨论与交流,敬请关注本博客和新浪微博songzi_tea.