相关知识
相关程序:
为了略去内部的一些程序调试,中间步骤去除,如有疑问,请看源程序
#include "stdafx.h"
//本节讲述 图像处理之 点多边形测试;
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;
void contours_Callback(int, void*);
Mat src, test1, test2, dst, gray_src, temp;
char input_title[] = "原图";
char output_title[] = "结果图";
void tiaojie(int, void*);
int value = 50;
int max_value = 255;
int main(int argc, char**argv)
{
//src = imread("C:/Users/Rubison.DELL/Desktop\\杂物/壁纸/热气球2.png"); //待检测图
src = imread("C:/Users/Rubison.DELL/Desktop\\杂物/壁纸/枫叶.jpg");
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);
GaussianBlur(src, src, Size(3, 3), 0);
//Canny(src, gray_src, 100, 250);
cvtColor(src,gray_src,CV_BGR2GRAY);
//imshow("dst", dst);*/
createTrackbar("阈值调节", input_title, &value, max_value, tiaojie);
tiaojie(0,0);
waitKey(0);
destroyAllWindows();
return 0;
}
void tiaojie(int, void*)
{
threshold(gray_src, dst, value,255, CV_THRESH_BINARY);
imshow("阈值后检查", dst);
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
//Mat dst_copy = dst.clone();
//Mat dst_copy; //存储检测到的轮廓
//dst.copyTo(dst_copy);
findContours(dst, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE); //为什经过findContours后,dst就变了?按道理来说不变呀
imshow("轮廓检查2", dst);
//imshow("dst", dst);*/
// 计算距离
Mat raw_dist(dst.size(), CV_32FC1); //显示距离图
for (int j = 0; j < dst.rows; j++)
{
for (int i = 0; i < dst.cols; i++)
{
raw_dist.at<float>(j, i) = (float)pointPolygonTest(contours[1], Point2f((float)i, (float)j), true);
}
}
imshow("距离图", raw_dist);
// 找到最大最小值, 后续做归一化处理
double minVal; double maxVal;
minMaxLoc(raw_dist, &minVal, &maxVal, 0, 0, Mat()); //在矩阵中需找全局的最大最小数。
minVal = abs(minVal);
maxVal = abs(maxVal);
Mat drawing = Mat::zeros(dst.size(), CV_8UC3); //最后显示处理图
for (int j = 0; j < dst.rows; j++)
{
for (int i = 0; i < dst.cols; i++)
{
double distance = raw_dist.at<float>(j, i);
if (raw_dist.at<float>(j, i) < 0) // 边界外部 越远离边缘,值越小(绝对值越大)
{
//drawing.at<Vec3b>(j, i)[0] = (uchar)(255 - abs(raw_dist.at<float>(j, i)) * 255 / minVal); //abs 取绝对值
//drawing.at<Vec3b>(j, i)[0] = (uchar)(abs(1 - distance / minVal) * 127);
drawing.at<Vec3b>(j, i)[0] = (uchar)(abs(1.0 - distance / minVal) * 230);
}
else if (raw_dist.at<float>(j, i) > 0) // 边界内部 越靠近内部,值越大
{
drawing.at<Vec3b>(j, i)[2] = (uchar)(255 - raw_dist.at<float>(j, i) * 255 / maxVal);
}
else //边界上
{
drawing.at<Vec3b>(j, i)[0] = 255;
drawing.at<Vec3b>(j, i)[1] = 255;
drawing.at<Vec3b>(j, i)[2] = 255;
}
}
}
/*const char* source_window = "Source";
namedWindow(source_window, WINDOW_AUTOSIZE);*/
//imshow("源图", dst);
namedWindow("Distance", WINDOW_AUTOSIZE);
imshow("Distance", drawing);
}
备注
关于点多边形测试中的一些代码测试:
1.对枫叶通过调节滑块进行阈值测试(2或者248即接近阈值最小和最大时显示的了轮廓最明显):
由于显示(发现轮廓后)图像时,边缘不够完整,将cvtcolor函数转换成canny()函数后,图像变的清晰了。
!!!****问题又来了虽然轮廓清楚了,但是距离图(显示填充的图)却一片漆黑????
再把canny和cvtclolor换回来,又好了?那么问题出现在两个函数上。
canny输出的是边缘信息,而cvtcolor输出的为灰度图,调试后,问题又出现在二值化处理处这个函数是为了处理灰度图所用的,然后进行pointPolygonTest(计算轮廓距离);而canny算法得出的就是一个轮廓,为什么pointPolygonTest检测后什么也没有????画一个矩形都能检测处,为什么canny算子轮廓检测不出?
不懂!头炸了!!
备注:
1.相关知识参考:添加链接描述
这位博主的调试结果有一张挺好看,但是没有程序,以后有时间再看吧: