openCv之点多边形测试-(检测一个多边形内部点的位置)

相关知识
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

相关程序:
为了略去内部的一些程序调试,中间步骤去除,如有疑问,请看源程序

#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.相关知识参考:添加链接描述
这位博主的调试结果有一张挺好看,但是没有程序,以后有时间再看吧:在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w5875895

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值