android - 当我将蓝色的整个可能色相范围赋予蓝色时,为什么inRange函数无法检测到蓝色?

标签 android opencv opencv3.0 hsv opencv4android

colorizer.org网站上,它们的HSV范围为H = 0-360,S = 0-100,V = 0-100。我们也知道OpenCV中的HSV范围是H = 0-180,S = 0-255,V = 0-255。

我想为任何一种蓝色(我们认为是蓝色)选择一个范围,所以我查看了colorizer.org,发现蓝色Hue的范围大约是170到270。因此我将这个Hue范围除以了2,得到85-135。

现在,我从网站上的预览中获取了彩色[H=216, S=96, V=67]的以下屏幕截图

enter image description here

然后,我在手机上运行该应用程序,并从笔记本电脑屏幕上捕获了以下相机框架。我了解HSV channel 值会在一定程度上与网站上的有所不同,因为在我捕获相机框架时,还有其他条件,例如房间中有其他光线(HSV中的V)等。

enter image description here

然后,我通过Mat将此Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_RGB2HSV_FULL);转换为HSV颜色空间,从而得到下图。

enter image description here

然后我调用了inRange函数:

Core.inRange(hsvImage, new Scalar(85, 50, 40), new Scalar(135, 255, 255), maskedImage);

这导致了以下maskedImage。

enter image description here

问题是,当我包含所有可能的蓝色色相范围时,为什么不检测蓝色?

重要:除了第一个原始图像外,所有图像都使用Highgui.imwrite函数存储在sdcard中,因此我可以将它们移动到计算机上以便在Stackoverflow上上传它们。您必须已经注意到,第一个原始屏幕截图中的蓝色在第二个图像中转换为红色。原因是由相机捕获的帧(即由手机相机捕获的第一个屏幕快照的照片/帧)是RGBA图像。但是,OpenCV在将所有图像保存到某些东西的sdcard时,默认情况下会将所有图像转换为BRG。因此,请确保原始图像为RGBA,并且仅由OpenCV在内部将其转换为BGR以保存到sdcard中。这就是为什么红色显示为蓝色。

最佳答案

使用此代码确实对我有用(C++):

    cv::Mat input = cv::imread("../inputData/HSV_RGB.jpg");

    //assuming your image to be in RGB format after loading:
    cv::Mat hsv;
    cv::cvtColor(input,hsv,CV_RGB2HSV);

    // hue range:
    cv::Mat mask;
    inRange(hsv, cv::Scalar(85, 50, 40), cv::Scalar(135, 255, 255), mask);

    cv::imshow("blue mask", mask);

我使用了此输入图像(虽然实际上是RGB图像,但以BGR格式保存和加载,这就是为什么我们必须使用RGB2HSV而不是BGR2HSV的原因):

enter image description here

产生这个面具:

enter image description here

与您的代码不同的是,我使用CV_RGB2HSV而不是CV_RGB2HSV_FULL。标记CV_RGB2HSV_FULL使用整个字节存储色相值,因此0 .. 360 degrees范围将缩放为0 .. 255而不是0 .. 180中的CV_RGB2HSV
我可以通过使用以下部分的代码来验证这一点:
    // use _FULL flag:
    cv::cvtColor(input,hsv,CV_RGB2HSV_FULL);
    // but scale the hue values accordingly:
    double hueScale = 2.0/1.41176470588;
    cv::Mat mask;
    // scale hue values:
    inRange(hsv, cv::Scalar(hueScale*85, 50, 40), cv::Scalar(hueScale*135, 255, 255), mask);

得到这个结果:

enter image description here

对于任何想要测试“正确”图像的人:

这是转换为BGR的输入:如果要直接使用该输入,则必须将转换从RGB2HSV转换为BGR2HSV。但是我认为最好也显示输入的BGR版本...

enter image description here

关于android - 当我将蓝色的整个可能色相范围赋予蓝色时,为什么inRange函数无法检测到蓝色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34200353/

相关文章:

android - 响应式网页表单在手机上输入奇怪的行为

python - 如何修复使用cv2.absdiff时该操作也不是 'array op array'

android - 霍夫圆不检测眼睛虹膜

python - BGR在OpenCV中的值(value)是什么?

android - asmack XMPP 新用户注册

java - 从 Imageview 中的图像中获取特定颜色的所有像素

python - OpenCV MergeMertens 在 Python 和 Python 中给出了不同的结果。 C++

opencv - 使用 opencv 在种植园航拍图像中分割树木的最佳方法

python - Raspberry Pi 3 - OpenCV 和 Picamera

java - 如果我在运行时只知道哪个资源,我如何从资源中获取字符串?