Android OpenCV dibujando líneas Hough
hough-transform (3)
Estoy tratando de usar OpenCV en un teléfono con Android para detectar líneas. Modifiqué la muestra ''Tutorial 1 Básico - 2. Usar OpenCV Camera''. También estoy usando Hough Line Transform como ejemplo. Sin embargo, estoy obteniendo números extraños (al menos lo que creo que son números extraños) por los puntos. En el rango 1000 a -1000 para b.
No entiendo completamente el código (principalmente la parte sobre la suma / resta de 1000 * (a o -b)).
Al final no veo las líneas en absoluto.
¿Alguien podría darme una mano? También déjame saber si necesitas más información.
capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
Imgproc.Canny(mGray, mIntermediateMat, 80, 100);
Imgproc.HoughLines(mIntermediateMat, mLines, 1, Math.PI/180, 100);
Scalar color = new Scalar(0, 0, 255);
double[] data;
double rho, theta;
Point pt1 = new Point();
Point pt2 = new Point();
double a, b;
double x0, y0;
for (int i = 0; i < mLines.cols(); i++)
{
data = mLines.get(0, i);
rho = data[0];
theta = data[1];
a = Math.cos(theta);
b = Math.sin(theta);
x0 = a*rho;
y0 = b*rho;
pt1.x = Math.round(x0 + 1000*(-b));
pt1.y = Math.round(y0 + 1000*a);
pt2.x = Math.round(x0 - 1000*(-b));
pt2.y = Math.round(y0 - 1000 *a);
Core.line(mIntermediateMat, pt1, pt2, color, 3);
}
Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2BGRA, 4);
Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
if (Utils.matToBitmap(mRgba, bmp))
return bmp;
bmp.recycle();
return null;
Aquí está mi código para el estudio visual, espero que ayude.
void drawLines(Mat &input, const std::vector<Vec2f> &lines) {
for (int i = 0; i < lines.size(); i++) {
float alpha = CV_PI/2-atan(input.rows/input.cols);
float r_max;
float r_min;
float r = lines[i][0];
float theta = lines[i][1];
if (theta<alpha || theta>CV_PI-alpha) {
r_max = input.cols*cos(theta);
r_min = input.rows*sin(theta);
if (r > r_max) {
Point pt1(input.cols, (r - input.cols*cos(theta)) / sin(theta));
Point pt2((r - input.rows*sin(theta)) / cos(theta), input.rows);
line(input, pt1, pt2, Scalar(255, 0, 0), 1);
}
else if (r < r_max && r > r_min) {
Point pt1(r / cos(theta), 0);
Point pt2((r - input.rows*sin(theta)) / cos(theta), input.rows);
line(input, pt1, pt2, Scalar(255, 0, 0), 1);
}
else {
Point pt1(r / cos(theta), 0);
Point pt2(0, r / sin(theta));
line(input, pt1, pt2, Scalar(255, 0, 0), 1);
}
}
else {
r_min = input.cols*cos(theta);
r_max = input.rows*sin(theta);
if (r > r_max) {
Point pt1(input.cols, (r - input.cols*cos(theta)) / sin(theta));
Point pt2((r - input.rows*sin(theta)) / cos(theta), input.rows);
line(input, pt1, pt2, Scalar(0, 0, 255), 1);
}
else if (r < r_max && r > r_min) {
Point pt1(input.cols, (r - input.cols*cos(theta)) / sin(theta));
Point pt2(0, r / sin(theta));
line(input, pt1, pt2, Scalar(0, 0, 255), 1);
}
else {
Point pt1(r / cos(theta), 0);
Point pt2(0, r / sin(theta));
line(input, pt1, pt2, Scalar(0, 0, 255), 1);
}
}
}
Aquí hay 2 gráficos sobre la lógica de mi código que publiqué.
La explicacion del alfa
La explicación de r_max && r_min
Dibuje las líneas en la imagen mIntermediateMat
, pero devolviendo la imagen mRgba
. Por eso no ves las líneas.
El rango de -1000..1000 para b
es correcto. HoughLines
devuelve un ángulo de línea y una distancia desde cero (también conocido como rho y theta ). Para dibujarlos, necesitas convertirlos en dos puntos. Los 1000 son las dimensiones de la imagen, si dibujara una imagen de 2000x2000, auméntela a 2000 o, de lo contrario, las líneas no cruzarán la imagen completa.
HoughLines
es un algoritmo diferente de HoughLinesP
. HoughLines
solo encuentra líneas, que cruzan toda la imagen. HoughLinesP
devuelve segmentos de línea más cortos.
Estoy usando HoughLineP para encontrar líneas en mi marco y dibujarlas de nuevo.
Aquí está mi código ... espero que esto ayude.
Mat mYuv = new Mat();
Mat mRgba = new Mat();
Mat thresholdImage = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1);
mYuv.put(0, 0, data);
Imgproc.cvtColor(mYuv, mRgba, Imgproc.COLOR_YUV420sp2RGB, 4);
Imgproc.cvtColor(mRgba, thresholdImage, Imgproc.COLOR_RGB2GRAY, 4);
Imgproc.Canny(thresholdImage, thresholdImage, 80, 100, 3);
Mat lines = new Mat();
int threshold = 50;
int minLineSize = 20;
int lineGap = 20;
Imgproc.HoughLinesP(thresholdImage, lines, 1, Math.PI/180, threshold, minLineSize, lineGap);
for (int x = 0; x < lines.cols(); 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);
}
Bitmap bmp = Bitmap.createBitmap(getFrameWidth(), getFrameHeight(), Bitmap.Config.ARGB_8888);
if (Utils.matToBitmap(mRgba, bmp))
return bmp;