opencv 图像轮廓

图片解析:

opencv 图像轮廓

原图:

opencv 图像轮廓

code:

#include <opencv\cv.h>

#include <opencv\highgui.h>

#include <opencv\cxcore.h>

#include <stdlib.h>

#include <stdio.h>

 

int main(int argc, char* argv[]){



#if 1

 

    int i, j;

 



    CvMemStorage* storage = cvCreateMemStorage(0);

	//以单通道方式加载图像

    IplImage* img = cvLoadImage("C:\\Users\\zxl\\Desktop\\0.png",CV_LOAD_IMAGE_GRAYSCALE);

	//常见一个等大小的3通道图像 (作为备份)

    IplImage* imgColor = cvCreateImage(cvGetSize(img),8,3);

	//用来显示轮廓的

	IplImage* contoursImage = cvCreateImage(cvSize(img->width,img->height),8,1);



    CvSeq* contours = 0 , *contoursTemp=0;

    cvZero(contoursImage);



    //对图像进行二值化

    cvThreshold(img,img,100,255,CV_THRESH_BINARY);

 

    //img的备份

    cvCvtColor(img,imgColor,CV_GRAY2BGR);

 



    // 提取图像img的轮廓信息函数 contours指向第一个轮廓 将轮廓存放在CvMemStorage类型的变量storage里面

	//&contours =>表示指针 指向能够提取的第一个轮廓  

	//CV_RETR_CCOMP =>表示轮廓的排列方式 有4种

	//-------------------------------------

	//CV_RETR_EXTERNAL 只返回最外面的轮廓

	//first=c0

	//CV_RETR_CCOMP 把外轮廓用双向链表的方式存放,有顺序 <从里到外><从右到左>

	//frist=c01001 <-> c01000 <-> c010 <-> c000 <-> c0

	//                              |        |      |

	//                            h0100    h0000    h01 <-> h00

	//CV_RETR_LIST 所有的轮廓(无分内外轮廓)通过1个链表的方式存储,<从里到外><从右到左>

	//first=c01001 <-> c01000 <-> h0100 <-> h0000 <-> c010 <-> c000 <-> h01 <-> h00 <-> c0

	//

	//

	//CV_RETR_TREE 按照树形结构存储,

	//first = c0

	//		  |

	//   h00 <->  h01

 	//	  |        |

	//  c000      c010

	//    |        |

	//  h0000   c01000 <-> c01001

	//-------------------------------------

	//CV_CHAIN_APPROX_NONE=> 轮廓显示是坐标的形式还是点的形式

	//提取轮廓后源图像会发生变化 所以需要用到开始生命的备份机制



	/*

	//备份机制检查原图 

	cvNamedWindow( "1");

    cvShowImage( "1", img );

	*/



    int total = cvFindContours( img, storage, &contours, sizeof(CvContour),

                    CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0) );



	/*

	//备份机制检查提取后

	cvNamedWindow( "2");

    cvShowImage( "2", img );

	cvWaitKey(0);

	*/





	//提取指针所指的地方

    contoursTemp = contours ;



    int count=0;

 

    //对轮廓进行循环

	//h_next 表示水平的方向上轮廓链接

	//v_next 表示垂直方向上的轮廓链接

    for(;contoursTemp!=0 ; contoursTemp=contoursTemp->h_next){ //通过这个循环访问每一个轮廓

            //提取外轮廓 上的所以坐标点

            for( i=0; i<contoursTemp->total; i++) {  //通过这个循环 得到坐标

                    CvPoint * pt = (CvPoint*)cvGetSeqElem(contoursTemp, i); // 读出第i个点。

                    //轮廓窗口让其显示为白色

					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); // 读出第i个点。

 

                            cvSetReal2D(contoursImage , pt->y , pt->x , 255.0);

                            cvSet2D(imgColor,pt->y,pt->x,cvScalar(0,255,0,0));

                    }

            }

    }

 

    cvNamedWindow( "image", 1 );

    cvShowImage( "image", imgColor );



    cvNamedWindow( "contours");

    cvShowImage("contours",contoursImage);

 

    cvWaitKey(0);

 



    cvReleaseMemStorage( &storage );

    cvReleaseImage( &img );

    cvReleaseImage(&contoursImage);

	cvReleaseImage(&imgColor);

 



#endif





	return 0;

}

 

效果:

opencv 图像轮廓

你可能感兴趣的:(opencv)