Android的OpenCV的颜色检测颜色、Android、OpenCV

2023-09-04 03:00:27 作者:将你推入深渊

目前我正在开发一个应用程序,将检测到彩色圆圈。我想通过以下这个教程,这里的家伙检测图像与Python红色圆圈。我已经写了同样的code,只为Java语言。

Currently I'm developing an app that will detect colored circles. I'm trying to do this by following this tutorial, where guy detects red circles on image with Python. I've written the same code, just for Java.

                    Mat mat = new Mat(bitmap.getWidth(), bitmap.getHeight(),
                            CvType.CV_8UC3);

                    Mat hsv_image = new Mat();
                    Utils.bitmapToMat(bitmap, mat);
                    Imgproc.cvtColor(mat, hsv_image, Imgproc.COLOR_BGR2HSV);

                    Mat lower_red_hue_range = new Mat();
                    Mat upper_red_hue_range = new Mat();

                    Core.inRange(hsv_image, new Scalar(0, 100, 100), new Scalar(10, 255, 255), lower_red_hue_range);
                    Core.inRange(hsv_image, new Scalar(160, 100, 100), new Scalar(179, 255, 255), upper_red_hue_range);
                    Utils.matToBitmap(hsv_image, bitmap);
                mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
                image.setImageBitmap(mutableBitmap);

图片我用的是相同的一个来自教程:

Image I use is identical to one from tutorial:

这是图像应用BGR2HSV:

This is image with applied BGR2HSV:

当我使用较低的红色色调范围执行code,它检测到的蓝色圆圈。当我使用上的红色色调范围它给了我黑色的BMP(没有检测到任何东西)。怎么可能?我究竟做错了什么?这是字面上的副本蟒蛇转移到Java。为什么是结果不同呢? 先谢谢了。

When I execute the code using lower red hue range, it detects the blue circle. When I use upper red hue range it gives me black bmp(doesn't detect anything). How can it be? What am I doing wrong? This is literally copy moved from python to Java. Why's the result different then? Thanks in advance.

推荐答案

CvType.CV_8UC1 的图像,即你正在使用的灰度图像。尝试使用 CvType.CV_8UC3

Your mat is of CvType.CV_8UC1 image, i.e. you are working on a grayscale image. Try with CvType.CV_8UC3

Mat mat = new Mat(bitmap.getWidth(), bitmap.getHeight(), CvType.CV_8UC3);

hsv_image 应该是这样的:

如何选择一个自定义的范围:

您可能需要检测的绿色的循环。 那么,在HSV,tipically的范围是:

You may want to detect a green circle. Well, in HSV, tipically the range is:

H in [0,360]
S,V in [0,100]

不过,对于 CV_8UC3 图像,每个分量H,S,V可以重新$ P $顶多psented只有256个值,因为它存储在1个字节。因此,在OpenCV中,范围H,S,V为 CV_8UC3 是:

However, for CV_8UC3 images, each component H,S,V can be represented by only 256 values at most, since it's stored in 1 byte. So, in OpenCV, the ranges H,S,V for CV_8UC3 are:

H in [0,180] <- halved to fit in the range
S,V in [0,255] <- stretched to fit the range

所以,从典型的范围OpenCV的范围,你需要切换:

So to switch from typical range to OpenCV range you need to:

opencv_H = typical_H / 2;
opencv_S = typical_S * 2.55; 
opencv_V = typical_V * 2.55;

所以,绿颜色是围绕120的色调色调的值可以在区间[0,360]的值。 然而,对于 Mat3b HSV图像,h的范围为[0,180],即减少了一半,因此它可以容纳一个8位再presentation至多256可能的值。 所以,您要求的H值为约120/2 = 60,说从50到70。 你还按顺序设置为S,V为100最小值为prevent非常暗的(几乎是黑色的)颜色。

So, green colors are around the value of hue of 120. The hue can have a value in the interval [0,360]. However, for Mat3b HSV images, the range for H is in [0,180], i.e. is halved so it can fit in a 8 bit representation with at most 256 possible values. So, you want the H value to be around 120 / 2 = 60, say from 50 to 70. You also set a minimum value for S,V to 100 in order to prevent very dark (almost black) colors.

Mat green_hue_range
inRange(hsv_image, cv::Scalar(50, 100, 100), cv::Scalar(70, 255, 255), green_hue_range);
 
精彩推荐
图片推荐