c++ - OpenCV:计算新的红色像素值

标签 c++ opencv image-processing pixel

我目前的目标是调整图像中的红色像素(更具体地说,是一个眼睛区域,以消除闪光灯引起的红眼),效果很好,但我遇到的问题是有时会出现绿色 Blob 皮肤。

这是一个很好的结果(之前和之后):

我知道为什么会这样,但是当我将阈值调整为更高的值(意味着红色强度必须更强)时,拾取和更改的红色像素更少,即:

阈值越低,皮肤上显示的绿色越多。

我想知道我目前正在做的改变红色像素的方法是否有替代方法?

int lcount = 0;
for(int y=0;y<lcroppedEye.rows;y++)
{
    for(int x=0;x<lcroppedEye.cols;x++)
    {
        double b = lcroppedEye.at<cv::Vec3b>(y, x)[0];
        double g = lcroppedEye.at<cv::Vec3b>(y, x)[1];
        double r = lcroppedEye.at<cv::Vec3b>(y, x)[2];

        double redIntensity = r / ((g + b) / 2);

        //currently causes issues with non-red-eye images
        if (redIntensity >= 1.8)
        {
            double newRedValue = (g + b) / 2;
            cv::Vec3b pixelColor(newRedValue,g,b);
            lroi.at<cv::Vec3b>(cv::Point(x,y)) = pixelColor;
            lcount++;
        }
    }
}

编辑: 我可能会添加一个检查以确保新的 RGB 值足够低,因此 R、G、B 值是相似/接近的值,因此黑色/灰色像素被写出仅...或具有不允许的 RGB 值范围(绿色)...这行得通吗?

最佳答案

在 RGB 空间中调整颜色有一些注意事项,例如您遇到的这个绿色区域。将 R、G、B 值转换为更好的颜色空间,如 HSV 或 LUV。

我建议您使用 HSV 来检测和更改红眼颜色。 R/(G+B) 不是计算红色强度的好方法。这意味着您将 (R=10,G=1,B=0) 称为非常红的颜色,但它是致命的黑色。看看下面的比较:

colors

因此,您最好检查饱和度和明度值是否为高值(红眼颜色就是这种情况)。如果您遇到其他高强度颜色,您可以检查色相是否在 [0-20] 和 [340-359] 范围内。但如果没有这个,您仍然可以安全地对抗白色本身,因为它的饱和度非常低,您无论如何也不会选择白色区域。

那是为了选择,为了改变颜色,最好不要使用 RGB,因为在我们感知颜色时,空间中的变化不是线性的。查看上图,您可以看到同时降低饱和度和值将是一个好的开始。但是您可以尝试一下,看看哪个看起来更好。也许你总是喜欢深灰色,这意味着将饱和度设置为零,并稍微降低值。您可能认为深棕色会更好,选择较低的饱和度和明度,但将色调设置为大约 30 度。

可能对您有帮助的引用资料:

  1. > Converting color values in OpenCV
  2. > An online tool to experiment with RGB and HSV colors

关于c++ - OpenCV:计算新的红色像素值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26480548/

相关文章:

c++ - 仅使用关键字和数字提取来解析简单语法

opencv - 为什么 cv::imencode 为 bgr8 和 mono8 图像提供相似大小的输出缓冲区?

c# - 如何使用 C# 裁剪图像?

c++ - 有条件地包含/排除类模板内的数据成员

c++ - 如何通过迭代器将 map<string, int> push_back 到 vector<map<string, int>> 中?

python - 将OpenCV中的比较运算符转换为Python

python - openCV:Sobel 边缘检测给我断言错误

image - 透视变换四边形平面中的给定点(x,y)到矩形平面的点(x',y')?

android - 使用opencv比较android中的两个图像

c++ - 我读取了一个 char 类型的变量,然后打印了 ascii 代码。为什么我按回车什么都没有?