Opencv:检测FFT上最亮的线
Opencv: detecting brightest line on FFT
我对我的图像进行了快速傅里叶变换,如下所示:
我想用边缘检测和霍夫变换得到这条明亮的水平线(我正在测量图像的旋转角度)。但是 Canny 算子效果不佳,因为颜色变化太小了。我怎样才能检测到那条线?
我这样生成 FFT:
dft = cv2.dft(frame, flags=cv2.DFT_COMPLEX_OUTPUT)
dft = np.fft.fftshift(dft)
spectrum = 20 * np.log(cv2.magnitude(dft[:, :, 0], dft[:, :, 1]))
# Converting to uint8 for Canny and HoughLinesP
spectrum = spectrum / np.max(spectrum) * 255
spectrum = spectrum.astype(np.uint8)
这是 Python/OpenCV 中的一种方法。
- 读取输入
- 转换为灰色并反转
- 应用自适应阈值并反转
- 应用形态学清理阈值并填充线
- 应用 Canny 边缘检测
- 应用霍夫线检测
- 画最大的线
- 保存结果
输入:
import cv2
import numpy as np
# read image
img = cv2.imread('fft.png')
# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = 255 - gray
# threshold
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 13, 3)
thresh = 255 - thresh
# apply close to connect the white areas
kernel = np.ones((3,3), np.uint8)
morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = np.ones((1,9), np.uint8)
morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)
# apply canny edge detection
edges = cv2.Canny(morph, 150, 200)
# get hough lines
result = img.copy()
lines = cv2.HoughLines(edges, 1, np.pi/180, 50)
# Draw line on the image
for rho,theta in lines[0]:
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(result, (x1, y1), (x2, y2), (0, 0, 255), 1)
# save resulting images
cv2.imwrite('fft_thresh.jpg',thresh)
cv2.imwrite('fft_morph.jpg',morph)
cv2.imwrite('fft_edges.jpg',edges)
cv2.imwrite('fft_line.jpg',result)
# show thresh and result
cv2.imshow("thresh", thresh)
cv2.imshow("morph", morph)
cv2.imshow("edges", edges)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
阈值图像:
形态学清理图像:
边缘图像:
在输入图像上绘制的结果 Hough 线:
我对我的图像进行了快速傅里叶变换,如下所示:
我想用边缘检测和霍夫变换得到这条明亮的水平线(我正在测量图像的旋转角度)。但是 Canny 算子效果不佳,因为颜色变化太小了。我怎样才能检测到那条线?
我这样生成 FFT:
dft = cv2.dft(frame, flags=cv2.DFT_COMPLEX_OUTPUT)
dft = np.fft.fftshift(dft)
spectrum = 20 * np.log(cv2.magnitude(dft[:, :, 0], dft[:, :, 1]))
# Converting to uint8 for Canny and HoughLinesP
spectrum = spectrum / np.max(spectrum) * 255
spectrum = spectrum.astype(np.uint8)
这是 Python/OpenCV 中的一种方法。
- 读取输入
- 转换为灰色并反转
- 应用自适应阈值并反转
- 应用形态学清理阈值并填充线
- 应用 Canny 边缘检测
- 应用霍夫线检测
- 画最大的线
- 保存结果
输入:
import cv2
import numpy as np
# read image
img = cv2.imread('fft.png')
# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = 255 - gray
# threshold
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 13, 3)
thresh = 255 - thresh
# apply close to connect the white areas
kernel = np.ones((3,3), np.uint8)
morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = np.ones((1,9), np.uint8)
morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)
# apply canny edge detection
edges = cv2.Canny(morph, 150, 200)
# get hough lines
result = img.copy()
lines = cv2.HoughLines(edges, 1, np.pi/180, 50)
# Draw line on the image
for rho,theta in lines[0]:
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(result, (x1, y1), (x2, y2), (0, 0, 255), 1)
# save resulting images
cv2.imwrite('fft_thresh.jpg',thresh)
cv2.imwrite('fft_morph.jpg',morph)
cv2.imwrite('fft_edges.jpg',edges)
cv2.imwrite('fft_line.jpg',result)
# show thresh and result
cv2.imshow("thresh", thresh)
cv2.imshow("morph", morph)
cv2.imshow("edges", edges)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
阈值图像:
形态学清理图像:
边缘图像:
在输入图像上绘制的结果 Hough 线: