《OpenCV3编程入门》学习笔记8 图像轮廓与图像分割修复(一)查找并绘制轮廓
第8章 圖像輪廓與圖像分割修復
8.1 查找并繪制輪廓
8.1.1 尋找輪廓:findContours()函數
1.作用:在二值圖像中尋找輪廓
2.函數原型:
void findcontours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())
3.參數說明:
(1)輸入圖像,8位單通道圖像,圖像非零像素被保留為0,所以圖像為二進制,可以使用cmopare()、inrange()、threshold()、adaptivethreshold()、canny()等函數由灰度圖或彩色圖創建二進制圖像
(2)檢測到的輪廓,每個輪廓存儲為一個點向量,即用point類型的vector表示
(3)可選的輸出向量,包含圖像的拓撲信息,作為輪廓數量的表示,每個輪廓contours[i]對應4個hierarchy元素,contours[i][0]~contours[i][3],分別表示后一個輪廓、前一個輪廓、父輪廓、內嵌輪廓的索引編號,如果沒有對應項,對應的hierarchy[i]值設為負數
(4)輪廓檢索模式,取值:
????????????
(5)輪廓近似辦法,取值:
????????????
(6)每個輪廓點的可選偏移量,默認值Point()
4.示例:
vector<vector<Point>>contours;
findContours(image,contours,RETR_EXTERNAL,CHAIN_APPROX_NONE);
8.1.2 繪制輪廓:drawContours()函數
1.作用:用于在圖像中繪制外部或內部輪廓
2.函數原型:
void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point())
3.參數說明:
(1)目標圖像
(2)輸入輪廓
(3)輪廓繪制指示變量,負值表示繪制所有輪廓
(4)輪廓顏色
(5)輪廓線條粗細度,默認值1,負值會繪制在輪廓內部
(6)線條類型,默認8,可取值:
????????????
(7)可選的層次結構信息,默認值noArray()
(8)用于繪制輪廓的最大等級,默認值INT_MAX
(9)可選的輪廓偏移參數,默認Point()
4.示例:
Mat result(image.size(),CV_8U,cv::Scalar(255));
drawContours(result,contours,-1,Scalar(0),3,8);
8.1.3 示例程序
1.查找并繪制輪廓示例
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{//以二值圖模式載入并顯示原圖Mat srcImage = imread("girl.jpg",0);if (!srcImage.data){printf("圖片載入失敗~!\n");return false;}imshow("【原始圖】", srcImage);//srcImage取大于閾值119的部分srcImage = srcImage > 119;imshow("取閾值后的原始圖", srcImage);//初始化結果圖Mat dstImage;dstImage=Mat::zeros(srcImage.rows,srcImage.cols, CV_8UC3);//定義輪廓和層次結構vector<vector<Point>>contours;vector<Vec4i>hierarchy;//查找輪廓findContours(srcImage, contours, hierarchy,RETR_CCOMP, CHAIN_APPROX_SIMPLE);//遍歷所有頂層輪廓,以隨機顏色繪制每個連接組件顏色for (int index = 0; index >= 0; index = hierarchy[index][0])//令index等于當前輪廓的下一個輪廓來更新循環,沒有下一輪廓時,hierarchy[i][0]為負值,循環結束{Scalar color(rand() & 255, rand() & 255, rand() & 255);drawContours(dstImage, contours, index,color, FILLED, 8,hierarchy);}//顯示輪廓圖imshow("【輪廓圖】", dstImage);waitKey(0);return 0;
}
運行效果:
2.綜合示例
/*
效果:利用圖像平滑和邊緣檢測,根據滑動條調節,動態檢測圖形輪廓
*/
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
#define WINDOW_NAME1 "【原始圖】"
#define WINDOW_NAME2 "【輪廓圖】"
//全局變量
Mat g_srcImage,g_grayImage,g_cannyMat_output,g_dstImage;
int g_nThresh = 80;
int g_nThresh_max = 255;
RNG g_rng(12345);
vector<vector<Point>>g_vContours;
vector<Vec4i>g_vHierarchy;
//全局函數
static void ShowHelpText();
static void on_ThreshChange(int, void*);
int main()
{//改變console字體顏色system("color 1F");ShowHelpText();//載入原圖g_srcImage = imread("girl.jpg", 1);if (!g_srcImage.data){printf("圖片載入失敗~!\n");return false;}//創建窗口namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);imshow(WINDOW_NAME1, g_srcImage);//轉成灰度圖并模糊化降噪cvtColor(g_srcImage, g_grayImage, CV_BGR2GRAY);blur(g_grayImage, g_grayImage, Size(3, 3));//創建滾動條并初始化createTrackbar("canny閾值", WINDOW_NAME2, &g_nThresh, g_nThresh_max, on_ThreshChange);on_ThreshChange(0, 0);waitKey(0);return 0;
}
static void on_ThreshChange(int, void*)
{//canny算子Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 2, 3);//查找輪廓findContours(g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));//繪制輪廓Mat g_dstImage = Mat::zeros(g_srcImage.rows, g_srcImage.cols, CV_8UC3);//或 for (int index = 0; index >= 0; index = g_vHierarchy[index][0])for (int index = 0; index < g_vContours.size(); index++){Scalar color(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//任意值drawContours(g_dstImage, g_vContours, index, color, 2, 8, g_vHierarchy, 0, Point());}//顯示效果圖imshow(WINDOW_NAME2, g_dstImage);
}
static void ShowHelpText()
{printf("\n\n\t歡迎來到【在圖形中尋找輪廓】示例程序!\n\n");printf("\n\n\t操作說明:\n\n");printf("\t\t鍵盤任意鍵-退出程序\n\n");printf("\t\t滑動滾動條-改變canny閾值\n");
}
運行效果:
總結
以上是生活随笔為你收集整理的《OpenCV3编程入门》学习笔记8 图像轮廓与图像分割修复(一)查找并绘制轮廓的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “萧条早寒至”上一句是什么
- 下一篇: 《OpenCV3编程入门》学习笔记8 图