4
社区成员
发帖
与我相关
我的任务
分享
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
class ImageProcessing:
def __init__(self, image_path):
self.image_path = image_path
self.img = cv.imread(self.image_path)
if self.img is None:
raise FileNotFoundError(f"无法读取图像文件: {self.image_path}")
def numpy_fourier_transform(self):
"""
使用Numpy进行傅里叶变换,并展示结果
"""
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
f = np.fft.fft2(img_gray)
fshift = np.fft.fftshift(f)
magnitude_spectrum = 20 * np.log(np.abs(fshift))
plt.subplot(1, 2, 1), plt.imshow(img_gray, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 2, 2), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()
rows, cols = img_gray.shape
crow, ccol = rows // 2, cols // 2
fshift[crow - 30:crow + 31, ccol - 30:ccol + 31] = 0
f_ishift = np.fft.ifftshift(fshift)
img_back = np.fft.ifft2(f_ishift)
img_back = np.real(img_back)
plt.subplot(1, 3, 1), plt.imshow(img_gray, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 3, 2), plt.imshow(img_back, cmap='gray')
plt.title('Image after HPF'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 3, 3), plt.imshow(img_back)
plt.title('Result in JET'), plt.xticks([]), plt.yticks([])
plt.show()
def opencv_fourier_transform(self):
"""
使用OpenCV进行傅里叶变换,并展示结果
"""
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
dft = cv.dft(np.float32(img_gray), flags=cv.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum = 20 * np.log(cv.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
plt.subplot(1, 2, 1), plt.imshow(img_gray, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 2, 2), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()
rows, cols = img_gray.shape
crow, ccol = rows // 2, cols // 2
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1
fshift = dft_shift * mask
f_ishift = np.fft.ifftshift(fshift)
img_back = cv.idft(f_ishift)
img_back = cv.magnitude(img_back[:, :, 0], img_back[:, :, 1])
plt.subplot(1, 2, 1), plt.imshow(img_gray, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 2, 2), plt.imshow(img_back, cmap='gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()
def show_filters(self):
"""
展示不同滤波器的频域响应
"""
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
# 没有缩放参数的简单均值滤波器
mean_filter = np.ones((3, 3))
# 创建高斯滤波器
x = cv.getGaussianKernel(5, 10)
gaussian = x * x.T
# 不同的边缘检测滤波器
# x方向上的scharr
scharr = np.array([[-3, 0, 3],
[-10, 0, 10],
[-3, 0, 3]])
# x方向上的sobel
sobel_x = np.array([[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]])
# y方向上的sobel
sobel_y = np.array([[-1, -2, -1],
[0, 0, 0],
[1, 2, 1]])
# 拉普拉斯变换
laplacian = np.array([[0, 1, 0],
[1, -4, 1],
[0, 1, 0]])
filters = [mean_filter, gaussian, laplacian, sobel_x, sobel_y, scharr]
filter_name = ['mean_filter', 'gaussian', 'laplacian','sobel_x',
'sobel_y','scharr_x']
fft_filters = [np.fft.fft2(x) for x in filters]
fft_shift = [np.fft.fftshift(y) for y in fft_filters]
mag_spectrum = [np.log(np.abs(z) + 1) for z in fft_shift]
for i in range(6):
plt.subplot(2, 3, i + 1), plt.imshow(mag_spectrum[i], cmap='gray')
plt.title(filter_name[i]), plt.xticks([]), plt.yticks([])
plt.show()
def template_matching(self, template_path):
"""
进行模板匹配,并展示不同方法的结果
:param template_path: 模板图像的路径
"""
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
template = cv.imread(template_path, 0)
if template is None:
raise FileNotFoundError(f"无法读取模板图像文件: {template_path}")
w, h = template.shape[::-1]
methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR',
'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']
for meth in methods:
img = img_gray.copy()
method = eval(meth)
res = cv.matchTemplate(img, template, method)
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv.rectangle(img, top_left, bottom_right, 255, 2)
plt.subplot(1, 2, 1), plt.imshow(res, cmap='gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 2, 2), plt.imshow(img, cmap='gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.suptitle(meth)
plt.show()
def multi_object_template_matching(self, template_path, threshold=0.8):
"""
进行多对象的模板匹配,并保存结果图像
:param template_path: 模板图像的路径
:param threshold: 匹配阈值,默认为0.8
"""
img_rgb = self.img.copy()
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
template = cv.imread(template_path, 0)
if template is None:
raise FileNotFoundError(f"无法读取模板图像文件: {template_path}")
w, h = template.shape[::-1]
res = cv.matchTemplate(img_gray, template, cv.TM_CCOEFF_NORMED)
loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]):
cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)
cv.imwrite('res.png', img_rgb)
def hough_line_transform(self):
"""
进行霍夫线变换,并保存结果图像
"""
img = self.img.copy()
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150, apertureSize=3)
lines = cv.HoughLines(edges, 1, np.pi / 180, 200)
for line in lines:
rho, theta = line[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))
cv.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv.imwrite('houghlines3.jpg', img)
def probabilistic_hough_line_transform(self):
"""
进行概率霍夫线变换,并保存结果图像
"""
img = self.img.copy()
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150, apertureSize=3)
lines = cv.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=100, maxLineGap=10)
for line in lines:
x1, y1, x2, y2 = line[0]
cv.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv.imwrite('houghlines5.jpg', img)
def hough_circle_transform(self):
"""
进行霍夫圈变换,并展示结果
"""
img_gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
img_gray = cv.medianBlur(img_gray, 5)
cimg = cv.cvtColor(img_gray, cv.COLOR_GRAY2BGR)
circles = cv.HoughCircles(img_gray, cv.HOUGH_GRADIENT, 1, 20,
param1=50, param2=30, minRadius=0, maxRadius=0)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0, :]:
# 绘制外圆
cv.circle(cimg, (i[0], i[1]), i[2], (0, 255, 0), 2)
# 绘制圆心
cv.circle(cimg, (i[0], i[1]), 2, (0, 0, 255), 3)
cv.imshow('detected circles', cimg)
cv.waitKey(0)
cv.destroyAllWindows()
def watershed_segmentation(self):
"""
进行图像分割与Watershed算法
"""
img = self.img.copy()
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)
# 噪声去除
kernel = np.ones((3, 3), np.uint8)
opening = cv.morphologyEx(thresh, cv.MORPH_OPEN, kernel, iterations=2)
# 确定背景区域
sure_bg = cv.dilate(opening, kernel, iterations=3)
# 寻找前景区域
dist_transform = cv.distanceTransform(opening, cv.DIST_L2, 5)
ret, sure_fg = cv.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)
# 找到未知区域
sure_fg = np.uint8(sure_fg)
unknown = cv.subtract(sure_bg, sure_fg)
# 类别标记
ret, markers = cv.connectedComponents(sure_fg)
# 为所有的标记加1,保证背景是0而不是1
markers = markers + 1
# 现在让所有的未知区域为0
markers[unknown == 255] = 0
markers = cv.watershed(img, markers)
img[markers == -1] = [255, 0, 0]
cv.imshow('Segmented Image', img)
cv.waitKey(0)
cv.destroyAllWindows()
def grabcut_foreground_extraction(self, rect=(50, 50, 450, 290), new_mask_path=None):
"""
使用GrabCut算法进行交互式前景提取
:param rect: 初始矩形框,默认为(50, 50, 450, 290)
:param new_mask_path: 新掩码图像的路径,如果为None则不使用新掩码,默认为None
"""
img = self.img.copy()
mask = np.zeros(img.shape[:2], np.uint8)
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)
cv.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv.GC_INIT_WITH_RECT)
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
img = img * mask2[:, :, np.newaxis]
plt.imshow(img), plt.colorbar(), plt.show()
if new_mask_path is not None:
newmask = cv.imread(new_mask_path, 0)
mask[newmask == 0] = 0
mask[newmask == 255] = 1
mask, bgdModel, fgdModel = cv.grabCut(img, mask, None, bgdModel, fgdModel, 5, cv.GC_INIT_WITH_MASK)
mask = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
img = img * mask[:, :, np.newaxis]
plt.imshow(img), plt.colorbar(), plt.show()