我的手机检测道路有问题。 我写了一些道路车道检测代码,但他没有为我工作。 从相机获得从正常视图到BGR颜色的修改,并尝试使用GausianBlur和Canny,但我认为我不是很好的绘制通道用于检测。 也许有些人对OpenCV如何检测道路有另一个想法?
Mat mYuv = new Mat(height + height / 2, width, CvType.CV_8UC1);
Mat mRgba = new Mat(height + height / 2, width, CvType.CV_8UC1);
Mat thresholdImage = new Mat(height + height / 2, width, CvType.CV_8UC1);
mYuv.put(0, 0, data);
Imgproc.cvtColor(mYuv, mRgba, Imgproc.COLOR_YUV420p2BGR, 4);
//convert to grayscale
Imgproc.cvtColor(mRgba, thresholdImage, Imgproc.COLOR_mRGBA2RGBA, 4);
// Perform a Gaussian blur (convolving in 5x5 Gaussian) & detect edges
Imgproc.GaussianBlur(mRgba, mRgba, new Size(5,5), 2.2, 2);
Imgproc.Canny(mRgba, thresholdImage, VActivity.CANNY_MIN_TRESHOLD, VActivity.CANNY_MAX_THRESHOLD);
Mat lines = new Mat();
double rho = 1;
double theta = Math.PI/180;
int threshold = 50;
//do Hough transform to find lanes
Imgproc.HoughLinesP(thresholdImage, lines, rho, theta, threshold, VActivity.HOUGH_MIN_LINE_LENGTH, VActivity.HOUGH_MAX_LINE_GAP);
for (int x = 0; x < lines.cols() && x < 1; x++){
double[] vec = lines.get(0, x);
double x1 = vec[0],
y1 = vec[1],
x2 = vec[2],
y2 = vec[3];
Point start = new Point(x1, y1);
Point end = new Point(x2, y2);
Core.line(mRgba, start, end, new Scalar(255, 0, 0), 3);
}
答案 0 :(得分:3)
这种方法很好,我做了类似的事情,不是用于道路线检测,但我注意到它可以用于那个目的。一些评论:
不确定为什么这样做:
Imgproc.cvtColor(mRgba, thresholdImage, Imgproc.COLOR_mRGBA2RGBA, 4);
为1.评论说转换为灰度,这是一个单一的通道和2. thresholdImage将被以后调用Canny覆盖。您只需要将thresholdImage标注为:
thresholdImage = new Mat(mRgba.size(), CvType.CV_8UC1);
对Canny的调用有什么参数值?我和我一起玩了很多,结果是:threshold1 = 441,threshold2 = 160,aperture = 3。
同样Imgproc.HoughLinesP:我使用Imgproc.HoughLines而不是Imgproc.HoughLinesP参数:threshold = 80,minLen = 30,maxLen = 10.
另请看:
for (int x = 0; x < lines.cols() && x < 1; x++){
&安培;&安培; x&lt; 1表示只接受HoughLinesP调用返回的第一行。我建议你删除它并使用一些其他标准来减少行数;例如,我只对水平和垂直线感兴趣,所以我使用atan2来计算线角度并排除那些偏离太多的线角度。
<强>更新强>
这是我如何得到一条线的角度。假设一个点的坐标是(x1,y1)而另一个点(x2,y2)那么得到角度:
double lineAngle = Math.atan2(y2 - y1, x2 - x1);
这应该返回-PI / 2和PI / 2之间的弧度角度
关于Canny参数然后我会进行实验 - 我设置了onTouch,以便我可以通过触摸屏幕的某些部分来实时查看效果来调整阈值。请注意,光圈是相当令人失望的参数:它似乎只有奇数值3,5和7和3是我发现的最佳值。
类似于onTouch方法:
int w = mRgba.width();
int h = mRgba.height();
float x = event.getX();
float y = event.getY();
if ((x < w / 3) && (y < h / 2)) t1 += 20;
if ((x < w / 3) && (y >= h / 2)) t1 -= 20;
if ((x > 2 * w / 3) && (y < h / 2)) t2 += 20;
if ((x > 2 * w / 3) && (y >= h / 2)) t2 -= 20;
t1和t2是传递给Canny呼叫的阈值。