c++ - 在相机图像中的监视器上查找白色像素

标签 c++ image-processing statistics

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

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

我还尝试计算具有最高值的 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();

最佳答案

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

伪代码:

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. 均值+标准差的阈值: Mask thresholded at mean+sd
  2. 扩张: Dilation
  3. 使用稍大的内核进行侵 eclipse ,以去除 1px 的细对象(例如线条),但保留靠近其他明亮对象的像素 Erosion
  4. 扩张以添加小于屏幕边框的边距: Dilation again
  5. 1 中的阈值掩码和 4 中的 toignore 被排除在外: Mask with dilated/eroded/dilated stuff ignored

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

关于c++ - 在相机图像中的监视器上查找白色像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16597669/

相关文章:

c++ - io_service::post 函数内的 boost::bind 组合

ios - 用 UIBezierPath 表示 CIRectangleFeature - Swift

opencv - 合并两个或多个部分重叠的图像

iphone - iOS:将 UIImageView 图像分解为形状并更改其颜色

c++ - clBuild 选项,传递 OpenCL 扩展

c++ - 使用cpp从r设置c++ rng种子

perl - 如何获得按键分组的平均值和标准差?

linux - 最佳鱿鱼日志文件分析工具

c++ - 使用 std::vector 缓冲区的高效输入处理

machine-learning - 迭代条件模式 E 步骤 EM