我有一个摄像头对准显示一行白色像素的显示器。我从相机返回了一组字节值。摄像头的视野面积大于显示器占用的空间。我需要找出白色监视器像素出现在相机图像上的位置。请参阅下面的示例图像。
我需要改进我的算法,使其在不同的光照条件下更加稳健。具体来说,我需要改进确定潜在白色像素值阈值的步骤。在确定哪些可能是我的白色像素后,我找到最大的邻域来确定我的最终白色值。
我还尝试计算具有最高值的 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
- 均值+标准差的阈值:
- 扩张:
- 使用稍大的内核进行侵 eclipse ,以去除 1px 的细对象(例如线条),但保留靠近其他明亮对象的像素
- 扩张以添加小于屏幕边框的边距:
- 1 中的阈值掩码和 4 中的 toignore 被排除在外:
还有一些杂散像素,但此时您可以进行霍夫变换。
关于c++ - 在相机图像中的监视器上查找白色像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16597669/