相关知识
相关程序
#include "stdafx.h"
//本节讲述 图像处理之 凸包-发现轮廓的进一步操作;
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;
void Threshold_Callback(int, void*);
Mat src, test1, test2, dst, gray_src, temp;
char input_title[] = "原图";
char output_title[] = "结果图";
int match_method = CV_TM_SQDIFF;
int max_track = 5;
int threshold_value = 50;
int max_threshold = 255;
int main(int argc, char**argv)
{
src = imread("C:/Users/Rubison.DELL/Desktop\\杂物/壁纸/.jpg"); //待检测图
//temp = imread("C:/Users/Rubison.DELL/Desktop\\杂物/壁纸/火箭队3.png"); //特征
if (src.empty())
{
printf("could not load image...\r\n");
return -1;
}
namedWindow(input_title, CV_WINDOW_AUTOSIZE);
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
imshow(input_title, src);
cvtColor(src, gray_src, CV_BGR2GRAY);
blur(gray_src, gray_src, Size(3, 3));
createTrackbar("Threshold Value",output_title, &threshold_value, max_threshold, Threshold_Callback);
Threshold_Callback(0, 0);
waitKey(0);
destroyAllWindows();
return 0;
}
void Threshold_Callback(int, void*)
{
//对图像进行二值化,控制阈值
Mat bin_output;
vector<vector<Point> > contours;//用于存放检测到的轮廓,数据类型为vector<vector>,每个轮廓中存放着属于该轮廓的像素坐标
vector<Vec4i> hierarchy; //用于存放各个轮廓之间的结构信息,数据类型为vector
threshold(gray_src, bin_output, threshold_value, max_threshold,THRESH_BINARY);
imshow("轮廓图", bin_output);
findContours(bin_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
//遍历每个轮廓,寻找其凸包
vector<vector<Point>> convexs(contours.size()); //轮廓/凸包尺寸的数组
for (size_t i = 1; i < contours.size(); i++)
{
convexHull(contours[i], convexs[i], false, true);
}
//绘制凸包
dst = Mat::zeros(src.size(),CV_8UC3);
RNG rng(12345);
for (size_t j = 0; j < contours.size(); j++)
{
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(dst, contours, j, color, 2, 8, hierarchy, 0, Point());
drawContours(dst, convexs, j, color, 2, 8, hierarchy, 0, Point());
}
imshow(output_title, dst);
}
运行结果
备注:
1.本章节核心API函数:convexHull()函数;并通过滑块来寻找最合适的阈值
2.可应用于计算面积!!