1

我有一个相机指向显示一行白色像素的显示器。我从相机返回一个字节值数组。摄像头的视野区域大于显示器占用的空间。我需要找出相机图像上白色监视器像素出现的位置。请参阅下面的示例图像。示例图像

我需要改进我的算法,使其在不同的光照条件下更加稳健。具体来说,我需要改进确定被视为潜在白色像素的值阈值的步骤。在确定什么可能是我的白色像素后,我找到最大的邻域来确定我的最终白色值。

我还尝试计算具有最高值的 N 个像素,并将 N 个像素的最低值视为白色。这在某些情况下工作得相当好,但当房间稍微变暗时它就停止工作了。我可以调整 N 以在任何光照条件下工作,但我宁愿不必手动提供任何参数。我现在正在尝试使用百分位数,但由于数据集非常大,因此运行速度很慢。

这是效果不错的方法之一,但必须在不同的光照条件下调整参数。

std::multiset<uint8_t> maxPixelValues;
for(unsigned i = 0; i < width; ++i)
{
    for(unsigned j = 0; j <height; ++j)
    {
        uint8_t pixelValue = buffer[j * width + i];
        if(maxPixelValues.size() < topPixelCount)
        {
            maxPixelValues.insert(pixelValue);
        }
        else
        {
            auto minimumValuePosition = maxPixelValues.begin();
            if(pixelValue > *minimumValuePosition)
            {
                maxPixelValues.erase(minimumValuePosition);
                maxPixelValues.insert(pixelValue);
            }
        }
    }
}
return *maxPixelValues.begin();
4

2 回答 2

3

首先,您可能希望将阈值设置为高于平均值的一个标准差,以消除屏幕较暗的部分。然后,您可以利用这样一个事实,即与背景中的一些较亮区域相比,线条非常细,并且由于屏幕边缘而远离其他明亮区域。

伪代码:

mask=threshold(img, mean(img)+stdev(img))
toignore=dilate(mask,3,3) 
toignore=erode(toignore,4,4) 
toignore=dilate(toignoe,3,3)
mask=mask &! toignore
  1. 平均值+标准差的阈值: 以均值 + 标准差为阈值的掩码
  2. 扩张: 扩张
  3. 使用稍大的内核进行侵蚀以去除 1px 的细物体(例如线条),但保留靠近其他明亮像素的像素 侵蚀
  4. 扩张以添加小于屏幕边框的边距: 再次膨胀
  5. 来自 1 的阈值掩码,排除了来自 4 的 toignore: 忽略扩张/侵蚀/扩张的面具

剩下一些杂散像素,但此时您可能可以进行霍夫变换。

于 2013-05-16T23:20:03.040 回答
0

您可以使用霍夫变换来查找图像上的线条:http ://en.wikipedia.org/wiki/Hough_transform

这是openCV api:http ://docs.opencv.org/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html

于 2013-05-16T21:27:32.987 回答