Android OpenCV速度交通标志检测
我在使用Android版opencv 2.4检测速度交通标志时遇到问题。 我做了以下工作: “捕获帧->将其转换为HSV->提取红色区域->使用椭圆检测检测标志” 到目前为止,椭圆检测工作完美,只要图片质量好。 但正如你们在下面的图片中看到的,我认为,由于画框质量差,红色提取不起作用 将原始图像转换为HSV:Android OpenCV速度交通标志检测,android,opencv,detection,traffic,hsv,Android,Opencv,Detection,Traffic,Hsv,我在使用Android版opencv 2.4检测速度交通标志时遇到问题。 我做了以下工作: “捕获帧->将其转换为HSV->提取红色区域->使用椭圆检测检测标志” 到目前为止,椭圆检测工作完美,只要图片质量好。 但正如你们在下面的图片中看到的,我认为,由于画框质量差,红色提取不起作用 将原始图像转换为HSV: Imgproc.cvtColor(this.source, this.source, Imgproc.COLOR_RGB2HSV, 3); Core.inRange(this.sourc
Imgproc.cvtColor(this.source, this.source, Imgproc.COLOR_RGB2HSV, 3);
Core.inRange(this.source, new Scalar(this.h,this.s,this.v), new Scalar(230,180,180), this.source);
private void findEllipses(Mat input){
Mat thresholdOutput = new Mat();
int thresh = 150;
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
MatOfInt4 hierarchy = new MatOfInt4();
Imgproc.threshold(source, thresholdOutput, thresh, 255, Imgproc.THRESH_BINARY);
//Imgproc.Canny(source, thresholdOutput, 50, 180);
Imgproc.findContours(source, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
RotatedRect minEllipse[] = new RotatedRect[contours.size()];
for(int i=0; i<contours.size();i++){
MatOfPoint2f temp=new MatOfPoint2f(contours.get(i).toArray());
if(temp.size().height > minEllipseSize && temp.size().height < maxEllipseSize){
double a = Imgproc.fitEllipse(temp).size.height;
double b = Imgproc.fitEllipse(temp).size.width;
if(Math.abs(a - b) < 10)
minEllipse[i] = Imgproc.fitEllipse(temp);
}
}
detectedObjects.clear();
for( int i = 0; i< contours.size(); i++ ){
Scalar color = new Scalar(180, 255, 180);
if(minEllipse[i] != null){
detectedObjects.add(new DetectedObject(minEllipse[i].center));
DetectedObject detectedObj = new DetectedObject(minEllipse[i].center);
Core.ellipse(source, minEllipse[i], color, 2, 8);
}
}
提取红色:
Imgproc.cvtColor(this.source, this.source, Imgproc.COLOR_RGB2HSV, 3);
Core.inRange(this.source, new Scalar(this.h,this.s,this.v), new Scalar(230,180,180), this.source);
private void findEllipses(Mat input){
Mat thresholdOutput = new Mat();
int thresh = 150;
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
MatOfInt4 hierarchy = new MatOfInt4();
Imgproc.threshold(source, thresholdOutput, thresh, 255, Imgproc.THRESH_BINARY);
//Imgproc.Canny(source, thresholdOutput, 50, 180);
Imgproc.findContours(source, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
RotatedRect minEllipse[] = new RotatedRect[contours.size()];
for(int i=0; i<contours.size();i++){
MatOfPoint2f temp=new MatOfPoint2f(contours.get(i).toArray());
if(temp.size().height > minEllipseSize && temp.size().height < maxEllipseSize){
double a = Imgproc.fitEllipse(temp).size.height;
double b = Imgproc.fitEllipse(temp).size.width;
if(Math.abs(a - b) < 10)
minEllipse[i] = Imgproc.fitEllipse(temp);
}
}
detectedObjects.clear();
for( int i = 0; i< contours.size(); i++ ){
Scalar color = new Scalar(180, 255, 180);
if(minEllipse[i] != null){
detectedObjects.add(new DetectedObject(minEllipse[i].center));
DetectedObject detectedObj = new DetectedObject(minEllipse[i].center);
Core.ellipse(source, minEllipse[i], color, 2, 8);
}
}
所以我的问题是,有没有其他方法可以检测像这样的交通标志,或者从中提取红色区域,顺便说一句,红色区域可能非常微弱,就像上一张图片一样?
这是原始图像:
这将转换为HSV,因为您可以看到红色区域与附近树木的颜色相同。这就是为什么我应该知道它是红色的,但我不能
转换为HSV:
这是用红色提取的。若颜色是正确的,我应该得到几乎完美的圆形/椭圆围绕符号,但由于错误的颜色,它是不完整的
提取后的结果:
椭圆方法:
Imgproc.cvtColor(this.source, this.source, Imgproc.COLOR_RGB2HSV, 3);
Core.inRange(this.source, new Scalar(this.h,this.s,this.v), new Scalar(230,180,180), this.source);
private void findEllipses(Mat input){
Mat thresholdOutput = new Mat();
int thresh = 150;
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
MatOfInt4 hierarchy = new MatOfInt4();
Imgproc.threshold(source, thresholdOutput, thresh, 255, Imgproc.THRESH_BINARY);
//Imgproc.Canny(source, thresholdOutput, 50, 180);
Imgproc.findContours(source, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
RotatedRect minEllipse[] = new RotatedRect[contours.size()];
for(int i=0; i<contours.size();i++){
MatOfPoint2f temp=new MatOfPoint2f(contours.get(i).toArray());
if(temp.size().height > minEllipseSize && temp.size().height < maxEllipseSize){
double a = Imgproc.fitEllipse(temp).size.height;
double b = Imgproc.fitEllipse(temp).size.width;
if(Math.abs(a - b) < 10)
minEllipse[i] = Imgproc.fitEllipse(temp);
}
}
detectedObjects.clear();
for( int i = 0; i< contours.size(); i++ ){
Scalar color = new Scalar(180, 255, 180);
if(minEllipse[i] != null){
detectedObjects.add(new DetectedObject(minEllipse[i].center));
DetectedObject detectedObj = new DetectedObject(minEllipse[i].center);
Core.ellipse(source, minEllipse[i], color, 2, 8);
}
}
private void findEllipses(Mat输入){
Mat阈值输出=新Mat();
int thresh=150;
列表等高线=新的ArrayList();
MatOfInt4层次结构=新的MatOfInt4();
Imgproc.threshold(源,thresholdOutput,threshold,255,Imgproc.threshold\u二进制);
//Imgproc.Canny(源,阈值输出,50,180);
Imgproc.findContours(源、轮廓、层次、Imgproc.RETR\u列表、Imgproc.CHAIN\u近似\u简单);
RotatedRect minEllipse[]=新的RotatedRect[contours.size()];
对于(int i=0;i minellipseize&&temp.size().height
}
问题符号:
您可以查阅交通标志检测方法和步骤
您将看到有两种方法可以实现这一点:
更新 我在没有任何预处理的情况下尝试了这个方法。您可以看到,至少红色边框的标志检测得非常好:
私有无效findEllipses(Mat输入){
Mat阈值输出=新Mat();
int thresh=150;
列表等高线=新的ArrayList();
MatOfInt4层次结构=新的MatOfInt4();
Imgproc.threshold(源,thresholdOutput,threshold,255,Imgproc.threshold\u二进制);
//Imgproc.Canny(源,阈值输出,50,180);
Imgproc.findContours(源、轮廓、层次、Imgproc.RETR\u列表、Imgproc.CHAIN\u近似\u简单);
//源=阈值输出;
RotatedRect minEllipse[]=新的RotatedRect[contours.size()];
对于(int i=0;i minellipseize&&temp.size().height
引用您的文本:
这将转换为HSV,因为您可以看到红色区域看起来是相同的颜色
就像附近的树一样。这就是为什么我应该知道它是红色的,但我不能
我想向您展示我对您所做的基本操作的结果(简单的操作应该可以很容易地转移到android openCV):
//转换为HSV
cv::Mat-hsv;
cv::cvtColor(输入,hsv,cv_BGR2HSV);
矢量信道;
cv::分割(hsv,通道);
//opencv=色调值除以2以适应8位范围
浮动红1=25/2.0f;
//红色的一部分在范围的开始处,一部分在范围的结束处(我假设0°到25°和335°到360°)
浮动红2=(360-25)/2.0f;
//计算两个t