OpenCV圖像輪廓檢測


輪廓檢測:

輪廓檢測的原理通俗的說就是掏空內部點,比如原圖中有3*3的矩形點。那么就可以將中間的那一點去掉。

一.關鍵函數
1.1  cvFindContours
函數功能:對圖像進行輪廓檢測,這個函數將生成一條鏈表以保存檢測出的各個輪廓信息,並傳出指向這條鏈表表頭的指針。
函數原型:
int cvFindContours(
  CvArr* image,                              第一個參數表示輸入圖像,必須為一個8位的二值圖像
  CvMemStorage* storage,            第二參數表示存儲輪廓的容器。為CvMemStorage類型,定義在OpenCV的\core\types_c.h中
  CvSeq** first_contour,             第三個參數為輸出參數,這個參數將指向用來存儲輪廓信息的鏈表表頭 

  int header_size=sizeof(CvContour),     第四個參數表示存儲輪廓鏈表的表頭大小,當第六個參數傳入CV_CHAIN_CODE時,
                                                                    要設置成sizeof(CvChain),其它情況統一設置成sizeof(CvContour)。

  int mode=    CV_RETR_LIST,                  第五個參數為輪廓檢測的模式,有如下取值:
      CV_RETR_EXTERNAL :     只檢索最外面的輪廓;
                        CV_RETR_LIST:                   檢索所有的輪廓,並將其保存到一條鏈表當中;
                        CV_RETR_CCOMP:             檢索所有的輪廓,並將他們組織為兩層:頂層是各部分的外部邊界,第二層是空洞的邊界;
                        CV_RETR_TREE:                 檢索所有的輪廓,並重構嵌套輪廓的整個層次;

  int method=   CV_CHAIN_APPROX_SIMPLE,              第六個參數用來表示輪廓邊緣的近似方法的,常用值如下所示:
                          CV_CHAIN_CODE:                                 以Freeman鏈碼的方式輸出輪廓,所有其他方法輸出多邊形(頂點的序列)。
                          CV_CHAIN_APPROX_SIMPLE:           壓縮水平的、垂直的和斜的部分,也就是,函數只保留他們的終點部分。

  CvPoint offset=cvPoint(0,0)                       第七個參數表示偏移量,比如你要從圖像的(100, 0)開始進行輪廓檢測,那么就傳入(100, 0)。

);

--->使用cvFindContours函數能檢測出圖像的輪廓,將輪廓繪制出來則需要另一函數——cvDrawContours來配合了。下面介紹cvDrawContours函數。

1.2  cvDrawContours
函數功能:在圖像上繪制外部和內部輪廓

函數原型:
void cvDrawContours(
  CvArr *img,                              第一個參數表示輸入圖像,函數將在這張圖像上繪制輪廓。
  CvSeq* contour,                       第二個參數表示指向輪廓鏈表的指針
  CvScalar external_color,
  CvScalar hole_color,                第三個參數和第四個參數表示顏色,繪制時會根據輪廓的層次來交替使用這二種顏色
  int max_level,                           第五個參數表示繪制輪廓的最大層數,如果是0,只繪制contour;如果是1,追加繪制和
                                                     contour同層的所有輪廓;如果是2,追加繪制比contour低一層的輪廓,以此類推;如果

                                                    值是負值,則函數並不繪制contour后的輪廓,但是將畫出其子輪廓,一直到abs(max_level) - 1層。


  int thickness=1,                       第六個參數表示輪廓線的寬度,如果為CV_FILLED則會填充輪廓內部
  int line_type=8,                       第七個參數表示輪廓線的類型。
  CvPoint offset=cvPoint(0,0)  第八個參數表示偏移量,如果傳入(10,20),那繪制將從圖像的(10,20)處開始
);

 

// ConsoleApplication1.cpp : 定義控制台應用程序的入口點。
//

#include "stdafx.h"
#include "iostream"
using namespace std;
#include "opencv2/opencv.hpp"

const char *pImagePath = "E:/C_VC_code/Text_Photo/girl005.jpg";
const char *pWindowsTitle = "原圖";
const char *pWindowsGrayTitle = "灰度圖";
const char *pWindowsBinaryTitle = "二值圖";
const char *pWindowsOutLineTitle = "輪廓圖";
const char *pWindowsToolBar = "閥值";
IplImage *pImage=NULL,*pGrayImage, *pBinaryImage, *pOutLineImage;
CvMemStorage *pMemStorage;
CvSeq *pSeq;
int nLevels = 3;
void functionCallback(int pos)
{
    cvThreshold(pGrayImage, pBinaryImage, pos, 255, CV_THRESH_BINARY);
    cvFindContours(pBinaryImage, pMemStorage, &pSeq ,sizeof(CvContour), CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));
    cvDrawContours(pOutLineImage, pSeq, CV_RGB(0,255,255), CV_RGB(255,0,0), nLevels, 2, 2);
    cvShowImage(pWindowsBinaryTitle, pBinaryImage);
    cvShowImage(pWindowsOutLineTitle, pOutLineImage);
}
void main()
{
    
    //SourceImage turn to GrayImage
    
    pImage = cvLoadImage(pImagePath, CV_LOAD_IMAGE_UNCHANGED);

    pGrayImage = cvCreateImage(cvGetSize(pImage), IPL_DEPTH_8U, 1);
    cvCvtColor(pImage, pGrayImage, CV_BGR2GRAY);

    //create window
    cvNamedWindow(pWindowsTitle, CV_WINDOW_AUTOSIZE);
    cvNamedWindow(pWindowsGrayTitle, CV_WINDOW_AUTOSIZE);
    cvNamedWindow(pWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);
    cvNamedWindow(pWindowsOutLineTitle, CV_WINDOW_AUTOSIZE);

    //為二值圖創建滑動條
    int nPos = 0;
    cvCreateTrackbar(pWindowsToolBar,pWindowsBinaryTitle,&nPos,100,functionCallback);

    //GrayImage turn into BinaryImage
    pBinaryImage = cvCreateImage(cvGetSize(pGrayImage), IPL_DEPTH_8U, 1);

    //檢索輪廓並返回檢測到的輪廓的個數
    pMemStorage = cvCreateMemStorage();
    pSeq = NULL;
    
    //Create and show OutLineImage
    pOutLineImage = cvCreateImage(cvGetSize(pBinaryImage), IPL_DEPTH_8U, 3);
    
    //填充成白色
    cvRectangle(pOutLineImage, cvPoint(0,0),cvPoint(pImage->width,pImage->height), CV_RGB(255,255,255), CV_FILLED);
    cvDrawContours(pOutLineImage, pSeq, CV_RGB(0,255,255), CV_RGB(255,0,0), nLevels, 2);


    cvShowImage(pWindowsTitle, pImage);
    cvShowImage(pWindowsGrayTitle, pGrayImage);
    cvShowImage(pWindowsBinaryTitle, pBinaryImage);
    cvShowImage(pWindowsOutLineTitle, pOutLineImage);

    functionCallback(100);

    //destroy object and release space
    cvWaitKey(0);
    cvDestroyWindow(pWindowsTitle);
    cvDestroyWindow(pWindowsGrayTitle);
    cvDestroyWindow(pWindowsBinaryTitle);
    cvDestroyWindow(pWindowsOutLineTitle);
    cvReleaseImage(&pImage);
    cvReleaseImage(&pGrayImage);
    cvReleaseImage(&pBinaryImage);
    cvReleaseImage(&pOutLineImage);

}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM