OpenCV 图像金字塔+通道分离+Canny算子求取边缘
2016-12-29 16:47
471 查看
OpenCV 图像金字塔+通道分离+Canny边缘的一个实例
学习OpenCV上一个不太完整的例子,对图像做两次金字塔缩小,做一次三通道分离得到一通道,再做Canny算子求边缘。把它完整填补了一下,写一下心得:// CannyWay.cpp -- Try Canny to find the contours #include <iostream> #include <opencv2/opencv.hpp> #include <ctime> #include <opencv/cv.h> #define _CRT_SECURE_NO_WARNINGS using namespace std; using namespace cv; IplImage* doCanny( IplImage* in, double lowThresh, double highThresh, int aperture ){ if (in->nChannels != 1) return(0); //Canny only handles gray scale images IplImage* out = cvCreateImage( cvSize(in->width, in->height), IPL_DEPTH_8U, 1); cvCanny(in, out, lowThresh, highThresh, aperture); return(out); } IplImage* doPyrDown( IplImage* in, int filter = IPL_GAUSSIAN_5x5 ){ // Best to make sure input image is divisable by two. // assert(in->width % 2 == 0 && in->height % 2 == 0); IplImage* out = cvCreateImage( cvSize(in->width / 2, in->height / 2), in->depth, in->nChannels); cvPyrDown(in, out); return(out); }; int main() { IplImage* img0 = cvLoadImage("timg.jpg"); IplImage* img1 = doPyrDown(img0, IPL_GAUSSIAN_5x5); IplImage* img2 = doPyrDown(img1, IPL_GAUSSIAN_5x5); IplImage* bimg2 = cvCreateImage(cvSize(img2->width, img2->height), 8, 1); IplImage* gimg2 = cvCreateImage(cvSize(img2->width, img2->height), 8, 1); IplImage* rimg2 = cvCreateImage(cvSize(img2->width, img2->height), 8, 1); cvSplit(img2, bimg2, gimg2, rimg2, 0); IplImage* img3 = doCanny(bimg2, 10, 100, 3); cvNamedWindow("OriginalPic", CV_WINDOW_AUTOSIZE); cvShowImage("OriginalPic", img0); cvNamedWindow("ZoomOUT1", CV_WINDOW_AUTOSIZE); cvShowImage("ZoomOUT1", img1); cvNamedWindow("ZoomOUT2", CV_WINDOW_AUTOSIZE); cvShowImage("ZoomOUT2", img2); cvNamedWindow("ZoomOUT3", CV_WINDOW_AUTOSIZE); cvShowImage("ZoomOUT3", img3); cvWaitKey(0); cvReleaseImage(&img0); cvReleaseImage(&img1); cvReleaseImage(&img2); cvReleaseImage(&img3); cvReleaseImage(&bimg2); cvReleaseImage(&gimg2); cvReleaseImage(&rimg2); cvDestroyAllWindows; return 0; }
图像金字塔要点
每次缩小之前做一次判断,如果长宽不都能被2整除,就放弃进行缩小。原因是cvPyrDown只能对可整除的长宽进行处理。
*这里有一些可以优化的地方,如果不能被2整除,可以考虑把不能被2整除的长或宽切掉一个像素。
IplImage* doPyrDown( IplImage* in, int filter = IPL_GAUSSIAN_5x5 ){ // Best to make sure input image is divisable by two. // assert(in->width >= 2 && in->height >= 2); IplImage* in2 = cvCreateImage(cvSize(floor(in->width/2)*2,floor(in->height/2)*2), in->depth, in->nChannels); CvRect Rect = cvRect(0, 0, floor(in->width/2)*2, floor(in->height/2)*2); cvSetImageROI(in, Rect); cvCopy(in, in2); IplImage* out = cvCreateImage( cvSize(in2->width / 2, in2->height / 2), in2->depth, in2->nChannels); cvPyrDown(in2, out); return(out); };
如下图所示大小变化
通道分离要点
注意到三个通道的命名,是反过来的,蓝色通道在前,红色通道在最后。
cvSplit(img2, bimg2, gimg2, rimg2, 0);
Canny算子求边缘要点
Canny只能对单通道图像直接运算,如果图像本身含有多个通道需要首先进行分离。
相关文章推荐
- opencv 学习第六天 通道的分离
- OpenCV—多通道颜色分离&混合
- Opencv图像识别从零到精通(31)----图像修补,分离合并通道
- OpenCV Python教程(2、图像元素的访问、通道分离与合并)
- OpenCV中用Canny算子进行边缘检测
- 6-python图像处理opencv(2.图像像素访问,通道分离与合并)
- opencv彩色图像通道分离
- opencv图像边缘检测Canny算子的总结分析
- OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器
- 【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
- OpenCV 分离颜色通道与多通道图像混合
- 【OpenCV】分离多通道图像RGB的值
- 【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
- 【OpenCV数字图像处理】(5) 【Python编程】(5) 像素访问之添加椒盐实例 通道分离与合并
- OpenCV 边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
- OpenCV之Canny算子边缘检测
- OpenCV分离图像通道
- OPENCV将多通道分离与合成、图像格式的转换
- 【OpenCV】图像的通道分离
- OpenCV 分离颜色通道与多通道图像混合