根据Miki的回答,这就是我所做的:

> Canny

> HoughLinesP(或LineSegmentDetector,如你所愿):检测线条

> ConnectedComponents:在Canny图像中找到Canny“轮廓”.

>具有3×3内核的膨胀(见下文)

>对于每个Hough线:从线上取几个像素并查找最常用的值(忽略0).

例如,我选择{p1,0.75 * p1 0.25 * p2,0.5 * p1 0.5 * p2,0.25 * p1 0.75 * p2,p2},所以如果我的值是{1,2,0,2,2}那么line属于connectedComponent number 2.

扩张是为了确保你没有错过一个轮廓只有1个像素(但如果你的对象太近,不要使用它).

这允许用它们所属轮廓的颜色“标记”HoughLines.

所有这些功能都可以在Imgproc模块中找到,这仅适用于OpenCV 3.0并提供所需的结果.

这是一个代码:

// open image

File root = Environment.getExternalStorageDirectory();

File file = new File(root, "image_test.png");

Mat mRGBA = Imgcodecs.imread(file.getAbsolutePath());

Imgproc.cvtColor(mRGBA, mRGBA, Imgproc.COLOR_BGR2RGB);

Mat mGray = new Mat();

Imgproc.cvtColor(mRGBA, mGray, Imgproc.COLOR_RGBA2GRAY);

Imgproc.medianBlur(mGray, mGray, 7);

/* Main part */

Imgproc.Canny(mGray, mGray, 50, 60, 3, true);

Mat aretes = new Mat();

Imgproc.HoughLinesP(mGray, aretes, 1, 0.01745329251, 30, 10, 4);

/**

* Tag Canny edges in the gray picture with indexes from 1 to 65535 (0 = background)

* (Make sure there are less than 255 components or convert mGray to 16U before)

*/

int nb = Imgproc.connectedComponents(mGray,mGray,8,CvType.CV_16U);

Imgproc.dilate(mGray, mGray, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3,3)));

// for each Hough line

for (int x = 0; x < aretes.rows(); x++) {

double[] vec = aretes.get(x, 0);

double x1 = vec[0],

y1 = vec[1],

x2 = vec[2],

y2 = vec[3];

/**

* Take 5 points from the line

*

* x----x----x----x----x

* P1 P2

*/

double[] pixel_values = new double[5];

pixel_values[0] = mGray.get((int) y1, (int) x1)[0];

pixel_values[1] = mGray.get((int) (y1*0.75 + y2*0.25), (int) (x1*0.75 + x2*0.25))[0];

pixel_values[2] = mGray.get((int) ((y1 + y2) *0.5), (int) ((x1 + x2) *0.5))[0];

pixel_values[3] = mGray.get((int) (y1*0.25 + y2*0.75), (int) (x1*0.25 + x2*0.75))[0];

pixel_values[4] = mGray.get((int) y2, (int) x2)[0];

/**

* Look for the most frequent value

* (To make it readable, the following code accepts the line only if there are at

* least 3 good pixels)

*/

double value;

Arrays.sort(pixel_values);

if (pixel_values[1] == pixel_values[3] || pixel_values[0] == pixel_values[2] || pixel_values[2] == pixel_values[4]) {

value = pixel_values[2];

}

else {

value = 0;

}

/**

* Now value is the index of the connected component (or 0 if it's a bad line)

* You can store it in an other array, here I'll just draw the line with the value

*/

if (value != 0) {

Imgproc.line(mRGBA,new Point(x1,y1),new Point(x2,y2),new Scalar((value * 41 + 50) % 255, (value * 69 + 100) % 255, (value * 91 + 60) % 255),3);

}

}

Imgproc.cvtColor(mRGBA, mRGBA, Imgproc.COLOR_RGB2BGR);

File file2 = new File(root, "image_test_OUT.png");

Imgcodecs.imwrite(file2.getAbsolutePath(), mRGBA);

pSQn8.png

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐