輪廓提取——主要針對二值圖像
<1> 輪廓分為外輪廓和內(nèi)輪廓 如下圖:外輪廓以c開頭 內(nèi)輪廓以h開頭
<2> opencv 提供了尋找輪廓的函數(shù) inttotals = cvFindContours(img, storage,&contours,sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE,cvPoint(0,0));
其中img是二值圖像,, storage是內(nèi)存存儲序列,, contours指向存儲的第一個輪廓,,
CvMemStorage *storage =cvCreateMemStorage(0); //內(nèi)存存儲序列
CvSeq *contours = 0; //指向storage中的序列
CV_RETR_LIST表明輪廓在內(nèi)存中的排列方式,,有以下四種:
輪廓的排列方式<在內(nèi)存中>
CV_RETR_EXTERNAL:first = c0
CV_RETR_CCOMP:從里到外 從右到左 這是一個雙向鏈表
CV_RETR_LIST:
first = c01001 <–> c01000 <–>h0100 <–> h0000 <–> h0100 <–> h0000 <–> c010 <–>c000 <–> h01 <–> h00 <–> c0 這也是雙向鏈表
CV_RETR_TREE:
<3>案例
結(jié)果展示:
代碼:
- #include <iostream>
- #include "cv.h"
- #include "cxcore.h"
- #include "highgui.h"
- using namespace std;
- int main()
- {
- CvMemStorage *storage = cvCreateMemStorage(0); // 內(nèi)存存儲序列
- IplImage *img = cvLoadImage("E:\\study_opencv_video\\lesson14_1\\Debug\\55.png", 0);
- IplImage *imgColor = cvCreateImage(cvGetSize(img), 8, 3);
- IplImage *contoursImage = cvCreateImage(cvGetSize(img), 8, 1);
-
- CvSeq *contours = 0, *contoursTemp = 0;
- cvZero(contoursImage);
- cvThreshold(img, img, 100, 255, CV_THRESH_BINARY); // 二值化操作
- cvCvtColor(img, imgColor, CV_GRAY2BGR);
- int totals = cvFindContours(img, storage,&contours, sizeof(CvContour), //img必須是一個二值圖像 storage 用來存儲的contours指向存儲的第一個輪廓
- CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
- contoursTemp = contours;
- int count = 0;
- int i;
- for(;contoursTemp != 0; contoursTemp = contoursTemp -> h_next) /// 這樣可以訪問每一個輪廓 ====橫向輪廓
- {
- for(i = 0; i < contoursTemp -> total; i++) // 提取一個輪廓的所有坐標(biāo)點(diǎn)
- {
- CvPoint *pt = (CvPoint*) cvGetSeqElem(contoursTemp, i); // 得到一個輪廓中一個點(diǎn)的函數(shù)cvGetSeqElem
- cvSetReal2D(contoursImage, pt->y, pt->x, 255.0);
- cvSet2D(imgColor, pt->y, pt->x, cvScalar(0,0,255,0));
- }
- count ++;
- CvSeq *InterCon = contoursTemp->v_next; // 訪問每個輪廓的縱向輪廓
- for(; InterCon != 0; InterCon = InterCon ->h_next)
- {
- for(i = 0; i < InterCon->total; i++ )
- {
- CvPoint *pt = (CvPoint*)cvGetSeqElem(InterCon, i);
- cvSetReal2D(contoursImage, pt->y, pt->x, 255.0);
- cvSet2D(imgColor, pt->y, pt->x, cvScalar(0, 255, 0, 0));
- }
- }
- }
- cvNamedWindow("contoursImage");
- cvShowImage("contoursImage", contoursImage);
- cvNamedWindow("imgColor");
- cvShowImage("imgColor",imgColor);
- cvWaitKey(0);
- cvReleaseMemStorage(&storage); // 也要釋放內(nèi)存序列空間
- cvReleaseImage(&contoursImage);
- cvReleaseImage(&imgColor);
- cvDestroyWindow("contoursImage");
- cvDestroyWindow("imgColor");
- return 0;<span style="font-family:Arial, Helvetica, sans-serif;">}</span>
作者:小村長 出處:http://blog.csdn.net/lu597203933 歡迎轉(zhuǎn)載或分享,,但請務(wù)必聲明文章出處。 (新浪微博:小村長zack, 歡迎交流?。?/span>
|