OpenCV,Android:来自特定区域或图像部分的颜色检测?
我想检测黑色物体下方的整个区域。OpenCV,Android:来自特定区域或图像部分的颜色检测?
我已经成功地得到下面的黑色物体的矩形区域,像这样
Point leftPoint = new Point(0,yValueBlack); //far left, black object height
Point rightPoint = new Point(sourceBitmap.getWidth(),sourceBitmap.getHeight()); //btm right of entire bitmap
Rect bottomRect = new Rect(leftPoint,rightPoint);
借助于此Rect bottomRect = new Rect(leftPoint,rightPoint);
是我想要检测的绿色条纹,就像图片中的区域。这是为了防止应用程序搜索图片上方的任何内容,并在其他对象在框架中时导致错误。
我有一个由边界矩形包围的黑色物体的位图,我只想从该位图检测到Rect bottomRect = new Rect(leftPoint,rightPoint);
&然后绘制绿色边界的边界矩形。
的方式,我定义我垫的尺寸是这样的 Mat sourceMat = new Mat(sourceBitmap.getWidth(), sourceBitmap.getHeight(), CvType.CV_8UC3);
但是当我试图用同样的方法来定义我的垫子大小,以适应下面的黑色物体的矩形区域,像这样: Mat croppedMat = new Mat(bottomRect, CvType.CV_8UC3);
这d给我一个错误。
下面是它会是什么样子,我认为:
Detect and draw bounding rectangle around black object (Done)
Find rectangle area(RAT) below black object
Detect and draw bounding rectangle around green object within the RAT(I can detect and draw bounding rectangle for green object, cant seem to do it WITHIN the specified RAT)
Display bitmap like shown in image below(done)
编辑:
检测的黑色物体后,将边界RECT绘制,目前正在roiBitmap
。裁剪roiBitmap
,并试图在imageview
来显示它(我会检测到来自该位图,它真实最终裁剪出来的绿色带)是给我的错误:
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 in function cv::Mat::Mat(const cv::Mat&, const cv::Range&, const cv::Range&)
我的代码:
private Bitmap findCombine(Bitmap sourceBitmap) {
Bitmap roiBitmap = null;
Scalar green = new Scalar(0, 255, 0, 255);
Mat sourceMat = new Mat(sourceBitmap.getWidth(), sourceBitmap.getHeight(), CvType.CV_8UC3);
Utils.bitmapToMat(sourceBitmap, sourceMat);
Mat roiTmp = sourceMat.clone();
bitmapWidth = sourceBitmap.getWidth();
Log.e("bitmapWidth", String.valueOf(bitmapWidth));
final Mat hsvMat = new Mat();
sourceMat.copyTo(hsvMat);
// convert mat to HSV format for Core.inRange()
Imgproc.cvtColor(hsvMat, hsvMat, Imgproc.COLOR_RGB2HSV);
Scalar lowerb = new Scalar(85, 50, 40); // lower color border for BLUE
Scalar upperb = new Scalar(135, 255, 255); // upper color border for BLUE
Scalar lowerblack = new Scalar(0, 0, 0); // lower color border for BLACK
Scalar upperblack = new Scalar(180, 255, 40); // upper color border for BLACK
Scalar testRunL = new Scalar(60, 50, 40); // lower Green 83 100 51
Scalar testRunU = new Scalar(90, 255, 255); // upper Green
Core.inRange(hsvMat, lowerblack, upperblack, roiTmp); // select only blue pixels
// find contours
List<MatOfPoint> contours = new ArrayList<>();
List<RotatedRect> boundingRects = new ArrayList<>();
Imgproc.findContours(roiTmp, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
// find appropriate bounding rectangles
for (MatOfPoint contour : contours) {
MatOfPoint2f areaPoints = new MatOfPoint2f(contour.toArray());
RotatedRect boundingRect = Imgproc.minAreaRect(areaPoints);
double rectangleArea = boundingRect.size.area();
// test min ROI area in pixels
if (rectangleArea > 1300 && rectangleArea < 500000) {//400000
Point rotated_rect_points[] = new Point[4];
boundingRect.points(rotated_rect_points);
Rect rect3 = Imgproc.boundingRect(new MatOfPoint(rotated_rect_points));
Log.e("blackArea", String.valueOf(rect3.area()));
// test horizontal ROI orientation
if (rect3.height > rect3.width) {
Imgproc.rectangle(sourceMat, rect3.tl(), rect3.br(), green, 3);
xBlack = rect3.br().x;
yBlack = rect3.br().y;//bottom
battHeight = (rect3.br().y - rect3.tl().y); //batt height in pixel
Log.e("BLACKBR, TL", String.valueOf(rect3.br().y) + "," + String.valueOf(rect3.tl().y));
}
}
}
roiBitmap = Bitmap.createBitmap(sourceMat.cols(), sourceMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(sourceMat, roiBitmap);
Point leftPoint = new Point(0, yBlack); //far left, black object height
Point rightPoint = new Point(roiBitmap.getWidth(), roiBitmap.getHeight()); //btm right of entire bitmap
Rect bottomRect = new Rect(leftPoint, rightPoint);
double rectWidth = sourceBitmap.getWidth() - 0;
double rectHeight = sourceBitmap.getHeight() - yBlack;
Log.e("rectWidth", String.valueOf(rectWidth));
Log.e("rectHeight", String.valueOf(rectHeight));
Size bottomRectSize = new Size(rectHeight, rectWidth);
Bitmap cropBitmap = null;
Bitmap sourceBitmapT = null;
Mat sourceMatT = new Mat(sourceBitmap.getWidth(), sourceBitmap.getHeight(), CvType.CV_8UC3);
Log.e("sourceMatT, BottomRect","SMT "+ String.valueOf(sourceMatT.size()) + " bottomRect " + String.valueOf(bottomRect.size()));
Mat cropMat = new Mat(sourceMatT, bottomRect);
ImageView imgCropped = (ImageView) findViewById(R.id.cropped_image_view);
Utils.bitmapToMat(roiBitmap, sourceMatT);
//mgCropped.setImageBitmap(sourceBitmapT);
Utils.matToBitmap(cropMat, cropBitmap);
imgCropped.setImageBitmap(cropBitmap);
Log.e("sourceMatT, BottomRect","SMT "+ String.valueOf(sourceMatT.size()) + " bottomRect " + String.valueOf(bottomRect.size()));
回到我这些值:
sourceMatT, BottomRect: SMT 1920x1080 bottomRect 1080x656
您可以“提取”图像的一部分,然后在整个提取区域中查找轮廓,然后修正查找轮廓的坐标。类似的东西:
提取部分sourceMat
:
// set top left position and dimensions of extracted area
int topLeftX = ...;
int topLeftY = ...;
int width = ...;
int height = ...;
// create Rect object for extracted area
Rect extractedRect = new Rect (topLeftX, topLeftY, width, height);
// create Mat from sourceMat
Mat extractedMat = new Mat(sourceMat, extractedRect);
查找轮廓/矩形或全部的提取区别的东西:
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(extractedMat, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
成立轮廓的正确COORDS(添加到它的X
和Y
coords,相应的,topLeftX
和topLeftY
正确放置在sourceMat
):
List<Rect> rectsOnSourcemat = new ArrayList<>();
for (MatOfPoint contour : contours) {
MatOfPoint2f contourPoints = new MatOfPoint2f(contour.toArray());
RotatedRect boundingRect = Imgproc.minAreaRect(areaPoints);
Point rotated_rect_points[] = new Point[4];
boundingRect.points(rotated_rect_points);
// correct coords here for sourceMat:
for (int ixPoint = 0; ixPoint < 4; ixPoint++) {
rotated_rect_points[ixPoint].x += topLeftX;
rotated_rect_points[ixPoint].y += topLeftY;
}
// crate bounding rect for sourceMat
Rect rect = Imgproc.boundingRect(new MatOfPoint(rotated_rect_points));
rectsOnSourcemat.add(rect);
}
现在在rectsOnSourcemat
变量您将得到建立在提取的区域对象上的rects列表,但已经与sourceMat
的坐标一致。
'Mat croppedMat = new Mat(bottomRect,CvType.CV_8UC3);'给出一个错误,因为没有这个_Mat_构造函数。我想你要找的是这个:“垫子(Mat m,Rect roi)'。下一次,请首先查看[documentation](http://docs.opencv.org/java/3.1.0/)。 –
嘿@ElouarnLaine我已经编辑了这个问题来反映我目前的问题:如果你能够弄清楚什么是错误的,我会非常感谢一些帮助非常感谢 – Tix