用android和opencv检测道路车道

时间:2014-01-05 09:51:35

标签: android opencv

我的手机检测道路有问题。 我写了一些道路车道检测代码,但他没有为我工作。 从相机获得从正常视图到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);
}

1 个答案:

答案 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呼叫的阈值。