我要如何检测到蓝色并在蓝色纸条的底部绘制一条线,以便使用该线进行像素距离计算?
我知道OpenCV有一个blob检测应用程序,可以绘制所选颜色周围的轮廓,但我需要应用程序自动检测颜色并向我提供其坐标,以便我可以应用。
canvas.drawLine(0, 0, 20, 20, p);
画线的操作是在从视频中提取出来的位图图像上完成的。
编辑: 当我测试它时,它不能检测到蓝色。我甚至在有蓝色和绿色纸张的图片上进行了测试,但输出没有检测到蓝色...
要划线。
Mat hsvMat = new Mat();
//Mat black_hue_range = new Mat();
//Core.inRange(hsvMat, new Scalar(0, 0, 0), new Scalar(180, 255, 30, 0), black_hue_range);
Mat blue_hue = new Mat();
Scalar lower_blue = new Scalar(110,50,50);
Scalar upper_blue = new Scalar(130,255,255);
//Convert BGR to HSV
Imgproc.cvtColor(srcMat, hsvMat, Imgproc.COLOR_BGR2HSV);
//Threshold the HSV image to get only blue colors
Core.inRange(hsvMat, lower_blue, upper_blue, blue_hue); // hue == a colour or shade
Mat tempMat22 = new Mat();
Core.bitwise_and(hsvMat,hsvMat,tempMat22,blue_hue);
Utils.matToBitmap(tempMat22, b);
//Bitmap mutableBitmap = b.copy(Bitmap.Config.ARGB_8888, true);
imgR.setImageBitmap(b);
编辑:
下面的代码返回了三个值,我假设是 H = data [0],S data [1],V = data [2]
现在我有了HSV值,怎么得到上限和下限呢?亚历山大·雷诺兹在这里给出的答案似乎是针对RGB而不是HSV。注意:我现在读取的颜色像素是绿色而不是蓝色。
E/data: H:90.0 S:113.0 V:144.0
if (getIntent().hasExtra("byteArray")) {
bitmap = BitmapFactory.decodeByteArray(getIntent().getByteArrayExtra("byteArray"), 0, getIntent().getByteArrayExtra("byteArray").length);
int width= bitmap.getWidth();
int height=bitmap.getHeight();
int centerX=width/2;
int centerY=height/2;
srcMat = new Mat();
Utils.bitmapToMat(bitmap, srcMat);
Imgproc.cvtColor(srcMat, srcMat, Imgproc.COLOR_BGR2HSV);
srcMat.convertTo(srcMat, CvType.CV_64FC3); //http://answers.opencv.org/question/14961/using-get-and-put-to-access-pixel-values-in-java/
double[] data = srcMat.get(centerX, centerY);
Log.e("data", String.valueOf("H:"+data[0]+" S:"+data[1]+" V:"+data[2]));
Log.e("dlength", String.valueOf(data.length));
Mat matHSV = new Mat(0,0,CvType.CV_64FC3);
通过添加以下三行代码,我会收到一个错误,说位图== null,所以我不确定像素读取是否有效。
matHSV.put(0,0,data);
Utils.matToBitmap(matHSV, bb);
imgDisplay.setImageBitmap(bb);
编辑2:
当尝试使用Rect
指定roi时,我遇到了一个错误:
由CvException引起[org.opencv.core.CvException:cv :: Exception:/build/master_pack-android/opencv/modules/core/src/matrix.cpp:483:error:(-215)0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows在函数cv :: Mat :: Mat中(const cv :: Mat&,const cv :: Range&,const cv :: Range&)
bitmap = globals.getBmp();
Mat srcMat = new Mat();
Utils.bitmapToMat(bitmap, srcMat);
Mat hsvMat = new Mat();
Imgproc.cvtColor(srcMat,hsvMat,Imgproc.COLOR_BGR2HSV);
Mat roiMat;
Rect rectangle = new Rect(177,1571,822,1680);// 177,1571(top right corner), 820,1680 (btm right) 820, 1565(topright)
roiMat = new Mat(hsvMat,rectangle);
Utils.matToBitmap(roiMat, temp);
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageBitmap(temp);
我还尝试使用 Range
:
Range rowRange = new Range(177, 822);
Range colRange = new Range(1571, 1680);
roiMat = new Mat(hsvMat, rowRange, colRange); // public Mat(Mat m, Range rowRange, Range colRange)
EDIT2.5:
changing:
roiMat = new Mat(hsvMat, rowRange, colRange);
to:
roiMat = new Mat(hsvMat, colRange, rowRange);
似乎已经解决了问题,但现在报错显示我的bmp为空。
编辑3: 最终成功转换了Alexander Reynolds回答的Python代码, 但我似乎无法查看结果,因为出现了错误:java.lang.IllegalArgumentException: bmp == null
java.lang.IllegalArgumentException: bmp == null
位于
Utils.matToBitmap(idk,temp);
bitmap = cn.getBmp();
Mat srcMat = new Mat();
Utils.bitmapToMat(bitmap, srcMat);
Mat hsvMat = new Mat();
Imgproc.cvtColor(srcMat,hsvMat,Imgproc.COLOR_BGR2HSV);
Mat roiMat;
Rect rectangle = new Rect(177,1571,822,1680);// 177,1571(top right corner), 820,1680 (btm right) 820, 1565(topright)
Range rowRange = new Range(177, 822);
Range colRange = new Range(1571, 1680);
roiMat = new Mat(hsvMat, colRange, rowRange); // public Mat(Mat m, Range rowRange, Range colRange)
MatOfDouble mu = new MatOfDouble();
MatOfDouble sig = new MatOfDouble();
Core.meanStdDev(roiMat,mu,sig);
double m = mu.get(0,0)[0];
double d = sig.get(0,0)[0];
int a = 9;
Log.e("m , d", "m "+String.valueOf(m)+" d"+String.valueOf(d));
Mat blue_mask = new Mat();
Core.inRange(hsvMat, new Scalar(m-a*d), new Scalar(m+a*d), blue_mask); // javadoc: inRange(src, lowerb, upperb, dst)
Mat idk = new Mat();
Core.bitwise_and(hsvMat,hsvMat,idk,blue_mask);
Utils.matToBitmap(idk,temp);
Bitmap mutableBitmap = temp.copy(Bitmap.Config.ARGB_8888, true);