我正在尝试检测最大/更大的矩形并将边界框绘制到检测到的区域。
我尝试了其他方法来检测轮廓边缘的完美边缘(无孔的边缘)。我搜索了stackoverflow并提出了解决方案
OpenCV sharpen the edges (edges with no holes)和Segmentation Edges
不适用于我的示例图像。
我想在以下两个图像上检测最大/更大的矩形
Original Image 1
和
Original Image 2
以下是在调用findcontour之前用于预处理图像的代码。
public Mat processGrayScaleImage(Mat grayImage){
Mat value = new Mat();
Mat sobx = new Mat();
Mat soby = new Mat();
Mat grad_abs_val_approx = new Mat();
Imgproc.GaussianBlur(grayImage, value, new Size(9, 9), 2, 2);
Mat imf = new Mat();
value.convertTo(imf, CV_32FC1, 0.5f, 0.5f);
Imgproc.Sobel(imf, sobx, -1, 1, 0);
Imgproc.Sobel(imf, soby, -1, 0, 1);
sobx = sobx.mul(sobx);
soby = soby.mul(soby);
Mat sumxy = new Mat();
//Core.add(sobx,soby, sumxy);
Core.addWeighted(sobx, 0.5, soby, 0.5, 0, sumxy);
Core.pow(sumxy, 0.5, grad_abs_val_approx);
sobx.release();
soby.release();
sumxy.release();;
Mat filtered = new Mat();
Imgproc.GaussianBlur(grad_abs_val_approx, filtered, new Size(9, 9), 2, 2);
grad_abs_val_approx.release();
final MatOfDouble mean = new MatOfDouble();
final MatOfDouble stdev = new MatOfDouble();
Core.meanStdDev(filtered, mean, stdev);
Mat thresholded = new Mat();
Imgproc.threshold(filtered, thresholded, mean.toArray()[0], 1.0, Imgproc.THRESH_TOZERO);
Mat converted = new Mat();
thresholded.convertTo(converted, CV_8UC1);
thresholded.release();
filtered.release();
return converted;
}
我还尝试了HSV颜色空间中的饱和度通道来代替灰色图像,但是它不起作用。
有人知道为什么它不能与上面发布的代码一起使用吗?
如何处理图像以锐化轮廓检测的边缘?
欢迎提供任何相关信息(Java或C++或Python)。
//更新:05/04/2017
我已经在第一张原始图像上测试了高斯的差异。结果对于轮廓检测没有用。生成的图像xhttps://i.stack.imgur.com/ONw9F.jpg
我使用的代码:
public static Mat dog(Mat grayImage){
Mat blur1 = new Mat();
Mat blur2 = new Mat();
Mat dog = new Mat();
int radius1 = 15;
int radius2 = radius1 + 6;
Imgproc.GaussianBlur(grayImage, blur1, new Size(radius1, radius1), 5);
Imgproc.GaussianBlur(grayImage, blur2, new Size(radius2, radius2), 5);
Core.absdiff(blur1, blur2, dog);
Core.multiply(dog, new Scalar(100), dog);
Imgproc.threshold(dog, dog, 55, 255, Imgproc.THRESH_BINARY_INV);
return dog;
}
我也尝试过在高斯差异之前应用CLAHE,这是结果[高斯与clahe差异的图像结果] xhttps://i.stack.imgur.com/DDbqg.jpg
更新#2
我已经按照下面的建议尝试了houghline,但是它不起作用。
这是我的代码应用于灰度图像
public static void houghLines(Mat greyImg, Context ctx){
Mat lines = new Mat();
Mat binary = new Mat();
Mat original = greyImg.clone();
int threshold = 35;
int minLineSize = 20;
int lineGap = 30;
Imgproc.Canny(greyImg, greyImg, 20, 30, 3, false);
Imgproc.HoughLinesP(greyImg, lines, 1, Math.PI/70, threshold, minLineSize, lineGap);
for (int x = 0; x < lines.rows(); x++)
{
double[] vec = lines.get(x, 0);
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);
double dx = x1 - x2;
double dy = y1 - y2;
double dist = Math.sqrt (dx*dx + dy*dy);
if(dist>300.d)
Imgproc.line(original, start, end, new Scalar(0,255, 0, 255),5);
}
}
我应用Canny后的结果图像xhttps://i.stack.imgur.com/VtGNl.jpg
以及最终结果xhttps://i.stack.imgur.com/KIUan.jpg
更新#3 :06/04/2017
我尝试了Houghlines,而不是HoughlinesP。这没用。下面是代码
public static void houghLines(Mat Original, Context ctx){
Mat lines = new Mat();
Mat binary = new Mat();
Mat greyImg = new Mat();
Mat im = Original.clone();
Imgproc.cvtColor(im, greyImg, Imgproc.COLOR_RGB2GRAY);
Imgproc.Canny(greyImg, binary, 20, 30, 3, true);
Imgproc.HoughLines(binary, lines, 1, Math.PI/70, 35);
for (int i = 0; i < lines.cols(); i++){
double data[] = lines.get(0, i);
double rho = data[0];
double theta = data[1];
double cosTheta = Math.cos(theta);
double sinTheta = Math.sin(theta);
double x0 = cosTheta * rho;
double y0 = sinTheta * rho;
Point pt1 = new Point(x0 + 10000 * (-sinTheta), y0 + 10000 * cosTheta);
Point pt2 = new Point(x0 - 10000 * (-sinTheta), y0 - 10000 * cosTheta);
Imgproc.line(im, pt1, pt2, new Scalar(0, 0, 200), 3);
}
}
上面的代码生成的canny图片:_https://i.stack.imgur.com/6k8sF.jpg
生成的图像行_https://i.stack.imgur.com/3e9CB.jpg
在撰写本文时,我还没有找到可行的解决方案。
有人对可行的解决方案有想法吗?
最佳答案
我尝试对您共享的图像进行快速检查。在稍微调整了canny和hough线的参数后,我得到了这个结果。不知道您需要哪种概括,请尝试一下。
这是我的代码:
import cv2 as cv2
import numpy as np
# fn = '2PeyG.jpg'
fn = 'qEFMj.jpg'
r_scale = 0.1
# OpenCV reads image with BGR format
img = cv2.imread(fn)
img = cv2.resize(img, (0, 0), fx=r_scale, fy=r_scale)
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(img, 20, 30, apertureSize=3)
lines = cv2.HoughLines(edges, 1, np.pi/70, 35)
for rho, theta in lines[0]:
if (np.pi/70 <= theta <= np.pi/7) or (2.056 < theta < 4.970) or (1.570 <= theta <= 1.600):
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
x1 = int(x0 + 1000*(-b))
y1 = int(y0 + 1000*(a))
x2 = int(x0 - 1000*(-b))
y2 = int(y0 - 1000*(a))
cv2.line(img,(x1,y1),(x2,y2),(0,0,255),1)
cv2.imshow('edges', edges)
cv2.imshow('overlay', img)
# cv2.imwrite('lines_overlay.png', img)
cv2.waitKey(3000)
我得到的结果是
我同意这不是您要查找的内容,而是一个很好的起点。希望这可以帮助 :)
关于opencv - 锐化边缘,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43209866/