简体   繁体   English

在相机图像中的显示器上查找白色像素

[英]Finding white pixels on monitor in camera image

I have a camera pointed at a monitor displaying a line of white pixels. 我有一个相机指向显示器,显示一行白色像素。 I get an array of byte values back from the camera. 我从相机中获取了一个字节值数组。 The area of the camera's view is larger than the space taken up by the monitor. 摄像机视图的区域大于显示器占用的空间。 I need to find out where on the camera image the white monitor pixels appear. 我需要找出相机图像上白色显示器像素出现的位置。 See the sample image below. 请参见下面的示例图片。 示例图像

I need to improve my algorithm so that it is more robust in varying lighting conditions. 我需要改进我的算法,以便在不同的光照条件下更加稳健。 Specifically, I need to improve the step where I determine the value threshold for what are considered potential white pixels. 具体来说,我需要改进确定被认为是潜在白色像素的值阈值的步骤。 After determining what are likely my white pixels, I find the largest neighborhood to determine my final white values. 在确定可能是我的白色像素后,我找到最大的邻域来确定我的最终白色值。

I also tried counting the N pixels with the highest values and considering the lowest value of the N pixels as white. 我还尝试计算具有最高值的N个像素并将N个像素的最低值视为白色。 This worked fairly well in some conditions, but it stopped working when the room got slightly darker. 这在某些条件下工作得相当好,但是当房间稍微变暗时它停止工作。 I can tweak N to work in any lighting condition, but I would prefer not to have to provide any parameters manually. 我可以调整N在任何光照条件下工作,但我宁愿不必手动提供任何参数。 I am experimenting with using percentiles now, but it is running quite slow since the data set is very large. 我现在正在尝试使用百分位数,但由于数据集非常大,因此运行速度非常慢。

Here's one of the methods that works decently, but the parameters have to be tweaked in different lighting conditions. 这是一种方法合理的方法,但参数必须在不同的光照条件下进行调整。

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();

First you might want to threshold at one standard deviation above the mean to get rid of the darker parts of the screen. 首先,您可能希望以高于均值的一个标准偏差进行阈值处理,以摆脱屏幕的较暗部分。 Then you can take advantage of the fact that the line is quite thin compared to some of the brighter area in the background and also far away from other bright areas thanks to the edge of the screen. 然后,您可以利用这样一个事实:与背景中的一些较亮区域相比,线条非常薄,并且由于屏幕的边缘,它也远离其他明亮区域。

Pseudocode: 伪代码:

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. Thresholding at mean+sd: 阈值+ sd的阈值: 掩码阈值为均值+ sd
  2. Dilation: 扩张: 扩张
  3. Erosion with slightly bigger kernel to remove 1px thin objects (such as the line), but keep pixels that are near other bright ones 使用略大的内核进行侵蚀以移除1px的薄物体(例如线条),但保留靠近其他明亮物体的像素 侵蚀
  4. Dilation to add a margin smaller than the screen border: 扩张以添加小于屏幕边框的边距: 再次膨胀
  5. Thresholded mask from 1 with toignore from 4 excluded: 来自1的阈值掩模与来自4的toignore排除: 掩盖扩张/侵蚀/扩张的东西被忽略

There are a few stray pixels left, but you can probably do a hough transform at this point. 剩下一些杂散像素,但你可以在这一点上进行霍夫变换。

You can use Hough transform to find lines on an image: http://en.wikipedia.org/wiki/Hough_transform 您可以使用Hough变换在图像上查找线条: http//en.wikipedia.org/wiki/Hough_transform

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM