Opencv學習筆記——利用二值圖像畫簡單輪廓

通過opencv自帶的cvFindContours函數可以對簡單地圖像進行輪廓分析,但要求利用圖像二值化能找到圖像的輪廓,具體實現代碼如下:

#include "stdio.h"
#include "cv.h"
#include "highgui.h"
    IplImage *g_image=NULL;
	IplImage *g_gray=NULL;
	int g_thresh=100;
	//設定閾值
	CvMemStorage *g_storage=NULL;
	//滑塊響應函數
    void on_trackbar(int frame)
	{
		if(g_storage==NULL)
		{
			g_gray=cvCreateImage(cvGetSize(g_image),8,1);
            g_storage=cvCreateMemStorage(0);//創造內存空間,存儲邊界
		}
		else
		{
			cvClearMemStorage(g_storage);//清空已有的數據
		}
		CvSeq *contours=0;//邊界序列
		cvCvtColor(g_image,g_gray,CV_BGR2GRAY);//將圖像轉化爲灰度圖
		cvThreshold(g_gray,g_gray,g_thresh,255,CV_THRESH_BINARY);//利用閾值二值化
		/*
		void cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type )
		src是初始矩陣,dst是處理後的矩陣,threshold是閾值大小,max_value是可提供的最大值,與後面的threshold_type配合使用,如:
        threshold_type:閾值類型 threshold_type=CV_THRESH_BINARY:
      如果 src(x,y)>threshold ,dst(x,y) = max_value; 否則,dst(x,y)=0;
		threshold_type=CV_THRESH_BINARY_INV:
  	如果 src(x,y)>threshold,dst(x,y) = 0; 否則,dst(x,y) = max_value.
		threshold_type=CV_THRESH_TRUNC:
  	如果 src(x,y)>threshold,dst(x,y) = threshold; 否則dst(x,y) = src(x,y).
		threshold_type=CV_THRESH_TOZERO:
  	如果src(x,y)>threshold,dst(x,y) = src(x,y) ; 否則 dst(x,y) = 0。
		threshold_type=CV_THRESH_TOZERO_INV:
  	如果 src(x,y)>threshold,dst(x,y) = 0 ; 否則dst(x,y) = src(x,y).
		*/
		cvNamedWindow("binaryImage",1);
		cvShowImage("binaryImage",g_gray);
		cvFindContours(g_gray,g_storage,&contours);
		/*
		cvFindContours從二值圖像中檢索輪廓,並返回檢測到的輪廓的個數
        cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour,
                            int header_size CV_DEFAULT(sizeof(CvContour)),
                            int mode CV_DEFAULT(CV_RETR_LIST),
                            int method CV_DEFAULT(CV_CHAIN_APPROX_SIMPLE),
                            CvPoint offset CV_DEFAULT(cvPoint(0,0)));
        img是已經二值化的圖像,storage返回的邊界,CvSeq是返回的邊界序列,是鏈式還是樹狀等由mode確定。header是返回輪廓的個數,
		method是提取輪廓的方法,offset是輪廓的偏移量,相當於起始點
		*/
		cvZero(g_gray);
		if(contours)
		{
			cvDrawContours(g_gray,contours,cvScalarAll(255),cvScalarAll(255),100);
			/*
			繪製輪廓的函數void cvDrawContours( CvArr *img, CvSeq* contour,
			CvScalar external_color, CvScalar hole_color,
			int max_level, int thickness=1,
			int line_type=8, CvPoint offset=cvPoint(0,0) );
            img是初始圖像,contour是輪廓序列,external_color是外輪廓的顏色,hole_color是內輪廓的顏色,max_level是所化輪廓最大層數,適用於完整輪廓裏面還有輪廓,如同心圓
           thickness是線的粗細,line_type是線的類型,offset是偏移量,也就是起始點
			*/
			cvShowImage("Contours",g_gray);
		}
	}
int main(int argc, char* argv[])
{
    g_image=cvLoadImage("2.jpg");
	IplImage *img=cvCreateImage(cvGetSize(g_image),8,3);
	cvCopyImage(g_image,img);
	cvNamedWindow("Contours",1);
	cvNamedWindow("src",1);
	cvShowImage("src",img);
	cvCreateTrackbar("Threshold","Contours",&g_thresh,1,on_trackbar);
	on_trackbar(0);
	cvWaitKey(0);
	
	
	printf("Hello World!\n");
	return 0;
}

實現結果如下:


發佈了45 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章