0

我正在 windows10 上开发 opencv 4.5.2,我的代码应该能够识别颜色。我在扫描一张 20x20 的简单图片时遇到了一个问题,它的颜色肯定是红色的。

在此处输入图像描述

当我运行以下代码段时

#include<opencv2/opencv.hpp>
#include<iostream>
const std::string imgpath = "C:\\Users\\nicola\\Desktop\\c++\\qt\\FaceScanner\\FaceScanner\\images\\";

int main()
{
    cv::Mat origin = cv::imread(imgpath+"square_red.jpg");
    cv::Mat hsv;
    cv::cvtColor(origin, hsv, cv::COLOR_BGR2HSV);
    cv::Scalar color = cv::mean(hsv);
    std::cout << "HSV: " << color[0] << " " << color[1] << " " << color[2] << "\n";
    color = cv::mean(origin);
    std::cout << "BGR: " << color[0] << " " << color[1] << " " << color[2] << "\n";
}

我得到的输出是

HSV: 88.4 251.532 238.768
BGR: 8.96 3.52 238.768

问题是这两种颜色不同,因为 hsv(88, 251, 238) 是一种绿色,而 bgr(8, 3, 238) 是我期待的红色。要在 hsv 颜色空间中处理我需要的颜色。任何人都可以解决这个问题吗?先感谢您。

4

1 回答 1

0

你不能只问色调角度的平均值。

算术平均值对角度没有意义。在这种情况下不是。

你的照片是红色的。红色的色相角约为 0。添加一些噪点,因为 JPEG 等等。这会让你的值0 左右,有一些小的正值和一些小的负值......除了,负值之后不会是负值cvtColor,它们会在 359 左右!359 是因为 360 度的圆周。可是等等!OpenCV 返回映射到的色调角度,0 .. 179因为 359 不适合uint8. 所以你有一些值在 0 左右,一些在 179 左右。

然后你平均一些 0 和一些 179... 你得到你的88.4,接近 90,这在数学上是有意义的,但是值(180 度,绿蓝色)完全是胡说八道,正如你所注意到的。

相反,在 RGB/BGR 或 YUV 空间中进行平均。它是有道理的,即定义明确。

一旦您在可以计算的颜色空间中获得了平均值,您就可以使用cvtColor它来转换它。我对 OpenCV 的 C++ API 不是很熟悉,所以如果cvtColor不按原样吃 Scalar,请将 Scalar 放入 Mat 中。

于 2021-12-27T10:11:23.133 回答