我一直在努力解决一个小问题一段时间,只是无法弄清楚出了什么问题。
所以我有一个黑色的126 x 126图像,带有1像素的蓝色边框([B,G,R] = [255,0,0])。 我想要的是距离所有蓝色像素(例如边框)最远的像素。我明白这是怎么做到的。遍历每个像素,如果它是黑色,则计算到每个其他像素的距离,蓝色寻找最小值,然后选择与任何蓝色的最小距离最大的黑色像素。
注意:我不需要真正知道真正的距离,所以当做距离的平方和我不是平方根时,我只想知道哪个距离更大(更便宜)。
我做的第一件事就是遍历每个像素,如果是蓝色,则将行和列添加到矢量中。我可以确认这部分是否正常工作。接下来,我再次遍历所有像素,并将每个黑色像素的距离与蓝色像素矢量中的每个像素进行比较。
其中blue是Blue对象的向量(有行和列) 区域是图像
int distance;
int localShortest = 0;
int bestDist = 0;
int posX = 0;
int posY = 0;
for(int i = 0; i < image.rows; i++)
{
for(int j = 0; j < image.cols; j++)
{
//Make sure pixel is black
if(image.at<cv::Vec3b>(i,j)[0] == 0
&& image.at<cv::Vec3b>(i,j)[1] == 0
&& image.at<cv::Vec3b>(i,j)[2] == 0)
{
for(int k = 0; k < blue.size(); k++)
{
//Distance between pixels
distance = (i - blue.at(k).row)*(i - blue.at(k).row) + (j - blue.at(k).col)*(j - blue.at(k).col);
if(k == 0)
{
localShortest = distance;
}
if(distance < localShortest)
{
localShortest = distance;
}
}
if(localShortest > bestDist)
{
posX = i;
posY = j;
bestDistance = localShortest;
}
}
}
}
对于边缘周围的1像素边框,这非常适用。 https://dl.dropboxusercontent.com/u/3879939/works.PNG
同样,如果我添加更多蓝色但保持方形ish黑色区域,那么它也可以。 https://dl.dropboxusercontent.com/u/3879939/alsoWorks.PNG
但是,一旦我使图像没有方形黑色部分,但可能是矩形。然后'最远的'关闭了。有时它甚至说蓝色像素离蓝色最远,这是不对的。
https://dl.dropboxusercontent.com/u/3879939/off.PNG
任何帮助非常感谢!伤了我一下头。
答案 0 :(得分:3)
无论如何,只要您使用OpenCV,一种可能性就是使用提供的distance transform function。
对于您的特定情况,您需要执行以下操作:
cv::distanceTransform
(欧几里德距离)CV_DIST_L2
函数
请注意,距边框最远距离可能有多个像素,因此您需要根据应用处理此情况。
距离变换中最亮的像素将是您需要的像素。例如,这是一个白色矩形及其距离变换:
答案 1 :(得分:2)
在正方形中,由于其对称性,最远的黑点(中心)也是最远的,无论你从哪个方向看。但现在试着想象一个非常长的矩形,高度很短。在其水平轴上将有多个点,最大的最小距离将是到顶侧和底侧的短距离,因为左侧和右侧都很远。在这种情况下,您的算法找到的像素可以是此行中的任何一个像素,结果将取决于您的像素扫描顺序。
答案 2 :(得分:0)
这是因为有一条线(多个像素)可以满足矩形
的条件