Android OpenCV颜色检测 [英] Android OpenCV Color detection

查看:3758
本文介绍了Android OpenCV颜色检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在开发一个可以检测彩色圆圈的应用程序。我想通过以下教程,其中家伙用Python检测图像上的红色圆圈。我写了相同的代码,只是为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);

我使用的图像与教程中的图像相同:



这是应用了BGR2HSV的图片:
< img src =https://i.stack.imgur.com/EYWz8.pngalt =enter image description here>



当我执行代码使用降低红色色调范围,它检测蓝色圆圈。当我使用上红色色调范围它给我黑色bmp(没有检测到任何东西)。怎么会这样?我做错了什么?这是字面上复制从python移动到Java。为什么结果不同?
提前感谢。

解决方案

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

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

hsv_image p>

>



如何选择自定义范围






想要检测绿色圈子。
在HSV中,范围是:

  H在[0,360] 
S,V但是,对于 CV_8UC3 ,在[0,100]


图像,每个分量H,S,V最多只能由256个值表示,因为它存储在1个字节。因此,在OpenCV中, CV_8UC3 的范围H,S,V是:

  H in [0,180] < - 减半以适合范围
S,V in [0,255] < - 延伸到适合范围

因此,要从典型范围切换到OpenCV范围,您需要:

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

因此,绿色的值在hue的值120附近。色调可以在区间[0,360]。
然而,对于 Mat3b HSV图像,H的范围在[0,180]中,即被减半,所以它可以适应8位表示,最多256可能的值。
所以,你希望H值在120/2 = 60左右,例如从50到70.
你还设置S的最小值,V到100,以防止非常暗黑色)颜色。

  Mat green_hue_range 
inRange(hsv_image,cv :: Scalar(50,100,100), cv :: Scalar(70,255,255),green_hue_range);


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:

This is image with applied BGR2HSV:

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.

解决方案

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 should look like this:

How to select a custom range:


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

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

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

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;

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);

这篇关于Android OpenCV颜色检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆