简体   繁体   English

使用 OpenCV 提高检测线的准确性

[英]Increase accuracy of detecting lines using OpenCV

I am implementing a program to detect lines in images from a camera.我正在实施一个程序来检测来自相机的图像中的线条。 The problem is that when the photo is blurry, my line detection algorithm misses a few lines.问题是当照片模糊时,我的线条检测算法会漏掉几条线条。 Is there a way to increase the accuracy of the cv.HoughLines() function without editing the parameters?有没有办法在不编辑参数的情况下提高cv.HoughLines()函数的准确性?

Example input image:示例输入图像:

模糊。

Desired image:想要的图片:

在此处输入图片说明

My current implementation:我目前的实现:

def find_lines(img):
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    edges = cv.dilate(gray,np.ones((3,3), np.uint8),iterations=5)
    edges = cv.Canny(gray, 50, 150, apertureSize=3)
    lines = cv.HoughLines(edges, 1, np.pi/180, 350)

It would be a good idea to preprocess the image before giving it to cv2.HoughLines() .在将图像提供给cv2.HoughLines()之前对图像进行预处理是个好主意。 Also I think cv2.HoughLinesP() would be better.另外我认为cv2.HoughLinesP()会更好。 Here's a simple approach这是一个简单的方法

  • Convert image to grayscale将图像转换为灰度
  • Apply a sharpening kernel应用锐化内核
  • Threshold image阈值图像
  • Perform morphological operations to smooth/filter image执行形态学操作以平滑/过滤图像

We apply a sharpening kernel using cv2.filter2D() which gives us the general shape of the line and removes the blurred sections.我们使用cv2.filter2D()应用锐化内核,它为我们提供了线条的一般形状并删除了模糊部分。 Other filters can be found here .其他过滤器可以在这里找到。

在此处输入图片说明

Now we threshold the image to get solid lines现在我们阈值图像以获得实线

在此处输入图片说明

There are small imperfections so we can use morphological operations with a cv2.MORPH_ELLIPSE kernel to get clean diamond shapes有一些小的缺陷,所以我们可以使用带有cv2.MORPH_ELLIPSE内核的形态学操作来获得干净的菱形形状

在此处输入图片说明

Finally to get the desired result, we dilate using the same kernel.最后为了得到想要的结果,我们使用相同的内核进行膨胀 Depending on the number of iterations, we can obtain thinner or wider lines根据迭代次数,我们可以获得更细或更宽的线条

Left ( iterations=2 ), Right ( iterations=3 )左( iterations=2 ),右( iterations=3

在此处输入图片说明 在此处输入图片说明

import cv2
import numpy as np

image = cv2.imread('1.png', 0)
sharpen_kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
sharpen = cv2.filter2D(image, -1, sharpen_kernel)
thresh = cv2.threshold(sharpen,220, 255,cv2.THRESH_BINARY)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=3)
result = cv2.dilate(opening, kernel, iterations=3)

cv2.imshow('thresh', thresh)
cv2.imshow('sharpen', sharpen)
cv2.imshow('opening', opening)
cv2.imshow('result', result)
cv2.waitKey()

You're looking for image sharpening techniques.您正在寻找图像锐化技术。 You'll find suggestions here .您会在此处找到建议。 You can use different kernel operations to achieve this.您可以使用不同的内核操作来实现这一点。 OpenCV lists this C++ code here OpenCV 在这里列出了这个 C++ 代码

 // sharpen image using "unsharp mask" algorithm
Mat blurred; double sigma = 1, threshold = 5, amount = 1;
GaussianBlur(img, blurred, Size(), sigma, sigma);
Mat lowContrastMask = abs(img - blurred) < threshold;
Mat sharpened = img*(1+amount) + blurred*(-amount);
img.copyTo(sharpened, lowContrastMask);

which should be fairly easy to convert to Python.这应该很容易转换为 Python。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM