Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我们如何从点上有特定颜色的图片中检测点_C++_Opencv_Image Processing - Fatal编程技术网

C++ 我们如何从点上有特定颜色的图片中检测点

C++ 我们如何从点上有特定颜色的图片中检测点,c++,opencv,image-processing,C++,Opencv,Image Processing,我有一系列的图片。我在这里发布了一个样本图像。 我需要从图像中提取特征,作为每个图像上绘制的60个标记的坐标。然后从鼻子上的一个特定标记,我需要找到所有其他标记的距离 我试图用openCV作为语言来完成这一点,并且正在阅读文档,但一周后我仍然无法实现目标。谁能给我指一下正确的方向吗。如果不是整个解决方案,请给我一个链接或一个教程,让我了解如何实现这一点 请参考我上传的图片。整个图像上的标记都涂成蓝色 任何帮助都将不胜感激。谢谢 这是我尝试过的代码,但结果却严重偏离了轨道 //This

我有一系列的图片。我在这里发布了一个样本图像。 我需要从图像中提取特征,作为每个图像上绘制的60个标记的坐标。然后从鼻子上的一个特定标记,我需要找到所有其他标记的距离

我试图用openCV作为语言来完成这一点,并且正在阅读文档,但一周后我仍然无法实现目标。谁能给我指一下正确的方向吗。如果不是整个解决方案,请给我一个链接或一个教程,让我了解如何实现这一点

请参考我上传的图片。整个图像上的标记都涂成蓝色

任何帮助都将不胜感激。谢谢

这是我尝试过的代码,但结果却严重偏离了轨道

     //This function threshold the HSV image and create a binary image
Mat GetThresholdedImage(Mat imgRGB){        
    Mat imgThresh;   
    inRange(imgRGB, Scalar(95,110,151), Scalar(112,125,169), imgThresh); 
    return imgThresh;
} 
int main(){
 Mat frame;
 frame = imread("other/test2.jpeg");
 namedWindow("Input");      
 namedWindow("Ball");

 Mat imgRGB=frame.clone();

 Mat imgThresh = GetThresholdedImage(imgRGB);


 imshow("Ball", imgThresh);            
 imshow("Input", frame);

 waitKey(0);
 return 0;
}

对于这样的问题,可以有多种解决方案来完成您想要做的事情。您可以使用OpenCV帮助自己实现这些函数。关于如何处理此类问题的一些建议:

从图像中分割蓝色标记。可能使用蓝色通道上的阈值来获取这些点。它们在蓝色通道中应该有相当高的值。 由于标记显示为多个像素,因此可以将蓝色的相邻像素视为一个簇,并找到每个簇标记的质心。 从鼻尖上的质心开始,计算到脸上每个簇质心的距离。 这也取决于一些事情。看起来这张图片中的衬衫有相当多的蓝色,所以它可能会被标记分割。要删除此项,可以使用OpenCV的人脸检测来查找人脸,然后只需担心找到的人脸区域

还取决于你是否知道鼻子标记在哪里。如果可以手动选择,则可以使用OpenCV执行此操作,可以在鼻子标记上设置种子,然后执行前面的步骤

如果无法手动选择,则基于此图像,如果使用鼻尖,则显示鼻子标记靠近图像中心。您可以找到离图像中心最近的质心并使用它。这样做将取决于您将测试的其他图像。此外,这种自动确定鼻子标记的方法可能不起作用,因为还有其他标记非常接近。你可以选择其中一个,而不是实际的鼻尖


正如我所说,这是一个相当主观的问题,可能有很多解决方案。这些只是一些建议,可能会帮助您找到正确的方向。

很容易找到所有使用与您类似代码的标记-您只需将图像转换为HSV颜色空间,而不是使用inRange函数-HSV颜色空间更适合此类任务,因为它“关注”颜色,而不是亮度。此代码:

Mat m = imread("D:\\face.jpg"), m2, m3;
cvtColor(m, m, CV_RGB2HSV);
resize(m, m, Size(m.cols/2, m.rows/2));
inRange(m, Scalar(0, 90, 50), Scalar(15, 175, 190), m2); 
imshow("qwe", m);
imshow("qwe2", m2);
dilate(m2, m3, Mat());
imshow("qwe", m);
imshow("qwe2", m2);
imshow("qwe3", m3);
waitKey(-1);
return 0;
关于此代码的几点: -当然,您必须更改文件的路径 -调整大小并不重要-我只使用了它,因为图像对于我的屏幕来说太大了 -通过查看HSV中显示的图像可以很容易地找到inRange scalar的值OpenCV将每个图像显示为3个通道的RGB图像,因此看起来有点奇怪-只需从窗口底部读取值可能您必须使用QT构建OpenCV,否则窗口将不包含此信息:注意-值的顺序与通常的YHSV不同,因此,如果您从屏幕底部读取颜色a、b、c,则应使用Scalarc、a、b

inRange后的结果: 最终结果:
如您所见,图像上还有其他对象,但是应该很容易检测和删除-只需在带有人脸的区域中查找标记使用人脸检测,或者只需为每个轮廓查找边界矩形,并检查边界矩形区域占轮廓区域的百分比-如果此值小于删除此轮廓,因为它与圆不相似。

请查看是否存在一些边界矩形区域好的切入点和样本!也许你可以用霍夫变换把蓝色标记检测成一个圆圈,这样你就不需要用人脸检测了。非常感谢你回答布鲁维的问题。我试试解决办法。我知道这些问题意味着我没有做好我的背景工作,但我只是不知道如何开始。请你详细说明一下。我需要找到蓝色标记的坐标来找到距离。@bruvel我试着按你说的做。我设置了一个阈值并试图检测这些区域。但结果严重偏离了轨道。我会在上面的问题中分享我的代码。非常感谢你,西瑞尔。这真的很有帮助。我只有一个问题。我如何找到范围。我试着用HSV,但就是没能把范围弄对。很抱歉我的回复太晚了,我被一个单独的项目缠住了。你可以从第一张图片上标记的窗口底部阅读它,或者只需创建一个简单的应用程序,为H、S、V上下边界和我们提供6个滑块
我可以为所有检测到的区域编号吗?我不确定你在问什么,但可能只需要使用函数findContours-