Java ColorBlobDetector OpenCV Android-找不到Blob
我是Android上openCV的新手,我正在使用openCV示例中的ColorBlobDetector类来检测红、绿、琥珀色等交通灯斑点。 我似乎不明白麦克洛拉迪厄斯的用法。 我也不知道在哪里比较颜色来找到合适的斑点我正在寻找 这是我的密码 PS:我甚至尝试输入Java ColorBlobDetector OpenCV Android-找不到Blob,java,android,opencv,Java,Android,Opencv,我是Android上openCV的新手,我正在使用openCV示例中的ColorBlobDetector类来检测红、绿、琥珀色等交通灯斑点。 我似乎不明白麦克洛拉迪厄斯的用法。 我也不知道在哪里比较颜色来找到合适的斑点我正在寻找 这是我的密码 PS:我甚至尝试输入mLowerBound和mupperboond的值,但它一直突出显示黑色斑点 package edu.csueb.ilab.blindbike.lightdetection; import android.os.Environment
mLowerBound
和mupperboond
的值,但它一直突出显示黑色斑点
package edu.csueb.ilab.blindbike.lightdetection;
import android.os.Environment;
import android.util.Log;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
// Lower and Upper bounds for range checking in HSV color space
private Scalar mLowerBound = new Scalar(0); //for blue 120,100,100 Current: 176,255,244 ::perfect working Green 70,20,100
// for flouracent green light 57,255,20
private Scalar mUpperBound = new Scalar(0); // for blue 179,255,255 , blue cap 28,28,37 Current: 177,255,252:: perfect working Green 85,35,125
// for flouracent green light 57,255,200
// for gray signs 76,55,28
// for gray signs 89,62,33 ,blue cap 80,109,149
// Minimum contour area in percent for contours filtering
private static double mMinContourArea = 0.01; //<></>ried 0.4
// Color radius for range checking in HSV color space
private Scalar mColorRadius = new Scalar(25,50,50,0); //initial val 25,50,50,0 //214,55,52,0 for the blue cap
private Mat mSpectrum = new Mat(); //
private List<MatOfPoint> mContours = new ArrayList<MatOfPoint>();
// Cache
Mat mPyrDownMat = new Mat();
Mat mHsvMat = new Mat();
Mat mMask = new Mat();
Mat mDilatedMask = new Mat();
Mat mHierarchy = new Mat();
SimpleDateFormat df= new SimpleDateFormat("yyyy_MM_dd_HH_mm_yyyy");
public void setColorRadius(Scalar radius) {
mColorRadius = radius;
}
public void setHsvColor(Scalar hsvColor) {
double minH = (hsvColor.val[0] >= mColorRadius.val[0]) ? hsvColor.val[0]-mColorRadius.val[0] : 0;
double maxH = (hsvColor.val[0]+mColorRadius.val[0] <= 255) ? hsvColor.val[0]+mColorRadius.val[0] : 255;
mLowerBound.val[0] = minH;
mUpperBound.val[0] = maxH;
mLowerBound.val[1] = hsvColor.val[1] - mColorRadius.val[1];
mUpperBound.val[1] = hsvColor.val[1] + mColorRadius.val[1];
mLowerBound.val[2] = hsvColor.val[2] - mColorRadius.val[2];
mUpperBound.val[2] = hsvColor.val[2] + mColorRadius.val[2];
mLowerBound.val[3] = 0;
mUpperBound.val[3] = 255;
Mat spectrumHsv = new Mat(1, (int)(maxH-minH), CvType.CV_8UC3);
for (int j = 0; j < maxH-minH; j++) {
byte[] tmp = {(byte)(minH+j), (byte)255, (byte)255};
spectrumHsv.put(0, j, tmp);
}
Imgproc.cvtColor(spectrumHsv, mSpectrum, Imgproc.COLOR_HSV2BGR_FULL, 4); //COLOR_HSV2RGB_FULL
}
public Mat getSpectrum() {
return mSpectrum;
}
public void setMinContourArea(double area) {
mMinContourArea = area;
}
public void process(Mat rgbaImage) {
Scalar colorGreen=new Scalar(0, 128, 0);
Imgproc.pyrDown(rgbaImage, mPyrDownMat);
Imgproc.pyrDown(mPyrDownMat, mPyrDownMat);
Imgproc.cvtColor(mPyrDownMat, mHsvMat, Imgproc.COLOR_BGR2HSV_FULL);
Core.inRange(mHsvMat, mLowerBound, mUpperBound, mMask);
Imgproc.dilate(mMask, mDilatedMask, new Mat());
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(mDilatedMask, contours, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
// Find max contour area
double maxArea = 0;
Iterator<MatOfPoint> each = contours.iterator();
while (each.hasNext()) {
MatOfPoint wrapper = each.next();
double area = Imgproc.contourArea(wrapper);
if (area > maxArea)
maxArea = area;
}
// Filter contours by area and resize to fit the original image size
mContours.clear();
each = contours.iterator();
while (each.hasNext()) {
MatOfPoint contour = each.next(); //Current: >=50 && <200 //testig at jan 9700 || 25200
if (Imgproc.contourArea(contour) >= 49656 || Imgproc.contourArea(contour)<53177) { //mMinContourArea*maxArea //red 30 300-440 green 510 1600
Core.multiply(contour, new Scalar(4,4), contour); //Perfect working: Green 880 || 1800
mContours.add(contour);
}
}
File path =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String filename = "christ"+df.format(new Date()).toString()+".png";
File file = new File(path, filename);
filename = file.toString();
Boolean save;
MatOfPoint2f approxCurve=new MatOfPoint2f();
for(int i=0;i<contours.size();i++)
{
MatOfPoint2f countour2f = new MatOfPoint2f(contours.get(i).toArray());
double approxDistance = Imgproc.arcLength(countour2f, true)*0.02;
Imgproc.approxPolyDP(countour2f, approxCurve, approxDistance, true);
// Convert back to Contour
MatOfPoint points=new MatOfPoint(approxCurve.toArray());
//Get Bounding rect of contour
Rect rect=Imgproc.boundingRect(points);
//draw enclosing rectangle
Mat ROI = rgbaImage.submat(rect.y, rect.y + rect.height, rect.x, rect.x + rect.width);
// save= Highgui.imwrite(filename,ROI);
// if (save == true)
// Log.i("Save Status", "SUCCESS writing image to external storage");
// else
// Log.i("Save Status", "Fail writing image to external storage");
Core.rectangle(rgbaImage, new Point(rect.x,rect.y), new Point(rect.x+rect.width,rect.y+rect.height),new Scalar(255,225,0,0),3);
}
}
public List<MatOfPoint> getContours() {
return mContours;
}
}
包edu.csueb.ilab.blindbike.lightdetection;
导入android.os.Environment;
导入android.util.Log;
导入org.opencv.core.core;
导入org.opencv.core.CvType;
导入org.opencv.core.Mat;
导入org.opencv.core.MatOfPoint;
导入org.opencv.core.MatOfPoint2f;
导入org.opencv.core.Point;
导入org.opencv.core.Rect;
导入org.opencv.core.Scalar;
导入org.opencv.highgui.highgui;
导入org.opencv.imgproc.imgproc;
导入java.io.File;
导入java.text.simpleDataFormat;
导入java.util.ArrayList;
导入java.util.Date;
导入java.util.Iterator;
导入java.util.List;
//HSV颜色空间中范围检查的上下限
私有标量mLowerBound=新标量(0)//对于蓝色120100100电流:176255244::完美工作绿色70,20100
//荧光绿灯57255,20
私有标量mupperbind=新标量(0);//对于蓝色179255255,蓝色帽28,28,37当前:177255252::完美工作绿色85,35125
//荧光绿灯57255200
//对于灰色标志76,55,28
//对于灰色标志89、62、33,蓝色标志80109149
//轮廓过滤的最小轮廓面积百分比
专用静态双通道面积=0.01//里德0.4
//HSV颜色空间中用于范围检查的颜色半径
私有标量mColorRadius=新标量(25,50,50,0)//蓝色帽的初始值25,50,50,0//214,55,52,0
专用Mat M谱=新Mat()//
private List mContours=new ArrayList();
//缓存
Mat mPyrDownMat=新的Mat();
材料mHsvMat=新材料();
Mat mMask=新Mat();
Mat mDilatedMask=新Mat();
Mat mHierarchy=新Mat();
SimpleDataFormat df=新的SimpleDataFormat(“yyyy_-MM_-dd_-HH_-MM_-yyyy”);
公共空间集合ColorRadius(标量半径){
mColorRadius=半径;
}
公共无效设置hsvColor(标量hsvColor){
double minH=(hsvColor.val[0]>=mColorRadius.val[0])?hsvColor.val[0]-mColorRadius.val[0]:0;
双最大值=(hsvColor.val[0]+mColorRadius.val[0]maxArea)
最大面积=面积;
}
//按区域过滤轮廓并调整大小以适合原始图像大小
mContours.clear();
each=等高线。迭代器();
while(each.hasNext()){
MatOfPoint contour=each.next();//当前:>=50&&=49656 | | Imgproc.contourArea(轮廓)作为一个起点看一下…可能会有帮助!谢谢Miki!我确实有我正在寻找的范围,我使用GIMP从训练图像中提取了这些范围。但是我无法确定我要使用哪些参数来比较颜色值。我最初尝试在setHsvColor()中设置MLOWERBOND和mUpperBound的值但是似乎不起作用。我不明白。顺便说一句,你的mColorRadius
基本上是链接答案中的敏感度
参数。哦!!!!这就是敏感度参数的用途!!哦,现在我似乎明白了。我确实使用了训练图像和photoshop提取了从HSV(129,2.55209)到HSV的红灯HSV值(159,2.55209)。但我不知道在哪里插入这些值以获得红色。最初我将mLowerBound和mUpperBound初始化为上述范围,但它检测到黑色。这是采样图像[链接]这似乎不是红色…看。另外,回到我链接的第一个答案,了解HSV中的范围。2.55是一个非常低的饱和度,它可能是错误的。此外,你需要为s和V通道提供更宽的范围。看看作为起点…可能会有帮助!谢谢Miki!我确实有我想要的范围,我需要额外的从使用GIMP的训练图像中提取。但我无法确定要使用哪些参数来比较颜色值。我最初尝试在setHsvColor()中设置mLowerBound和mupperbind的值但是似乎不起作用。我不明白。顺便说一句,你的mColorRadius
基本上是链接答案中的敏感度
参数。哦!!!!这就是敏感度参数的用途!!哦,现在我似乎明白了。我确实使用了训练图像和photoshop提取了从HSV(129,2.55209)到HSV的红灯HSV值(159,2.55209)。但我不知道在哪里插入这些值以获得红色。最初我将mLowerBound和mUpperBound初始化为上述范围,但它检测到黑色。这是采样图像[链接]这看起来不是红色…看。另外,回到我链接的第一个答案,了解HSV中的范围。2.55是一个非常低的饱和度,可能是错误的。另外,你需要为s和V通道提供更宽的范围。