数字图像处理实验思考题
数字图像处理实验的思考题汇总(实验三到实验六)。实验一没有思考题,实验二本人的实现效果不是很好,就不放出来献丑了。
实验三
通过鼠标操作在图像上选取任意4边形区域,通过仿射变换到指定的矩形区域。例如梯形到矩形的变换。提示:应用场景,例如将手机拍摄的梯形图片,通过几何操作,变的方方正正。
import cv2
import numpy as np
# 顺时针
def on_mouse(event, x, y, flag, param):
global X, Y, img, index, ix, iy, jx, jy
if event == cv2.EVENT_LBUTTONUP and index < 4:
X[index], Y[index] = x, y
if index == 0:
cv2.line(img, (x, y), (x, y), (0, 0, 255), 3)
elif index == 1:
cv2.line(img, (x, y), (X[index - 1], Y[index - 1]), (0, 0, 255), 3)
elif index == 2:
cv2.line(img, (x, y), (X[index - 1], Y[index - 1]), (0, 0, 255), 3)
elif index == 3:
cv2.line(img, (x, y), (X[index - 1], Y[index - 1]), (0, 0, 255), 3)
cv2.line(img, (x, y), (X[0], Y[0]), (0, 0, 255), 3)
index += 1
elif event == cv2.EVENT_LBUTTONDOWN and index == 4:
ix, iy = x, y
elif event == cv2.EVENT_LBUTTONUP and index == 4:
cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 1)
jx, jy = x, y
index += 1
if __name__ == '__main__':
img = cv2.imread('ppt.jpg')
cols, rows = img.shape[:2]
X = [-1, -1, -1, -1]
Y = [-1, -1, -1, -1]
ix, iy, jx, jy = -1, -1, -1, -1
index = 0
cv2.namedWindow('image')
cv2.setMouseCallback('image', on_mouse)
while 1:
cv2.imshow('image', img)
if index > 4:
pts1 = np.float32([[X[0], Y[0]], [X[1], Y[1]], [X[2], Y[2]]])
pts2 = np.float32([[ix, iy], [jx, iy], [jx, jy]])
M = cv2.getAffineTransform(pts1, pts2)
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('output', dst)
if cv2.waitKey(20) & 0xFF == 27:
break
cv2.destroyAllWindows()
注:先点出要进行仿射变换的四边形的顶点(从左上角开始,顺时针),再拖拽鼠标左键框出要变换到的矩形位置。
效果:
实验四
- 给出彩色图像Fig6,请在HSI空间对图像的亮度分量进行均衡化,观察彩色图像效果。
注:opencv中没有转为HSI空间的库函数,需要自己写,但效果不是很好。故转为HSV空间实现。
import cv2
import numpy as np
import math
from matplotlib import pyplot as plt
if __name__ == '__main__':
rgb_img = cv2.imread("Fig6.png")
hsv_img = cv2.cvtColor(rgb_img, cv2.COLOR_BGR2HSV)
cv2.imshow("hsv", hsv_img)
h, s, v = cv2.split(hsv_img)
equ = cv2.equalizeHist(v)
res_img = cv2.merge([h, s, equ])
cv2.imshow("hsv_equ", res_img)
ans_img = cv2.cvtColor(res_img, cv2.COLOR_HSV2BGR)
cv2.imshow("original", rgb_img)
cv2.imshow("ans", ans_img)
key = cv2.waitKey(0) & 0xFF
if key == ord('q'):
cv2.destroyAllWindows()
效果:
-
对同一幅图像Fig6在B、G、R空间逐一做均衡化处理,观察最终的图像与思考题1中的结果异同。
import cv2 import numpy from matplotlib import pyplot as plt if __name__ == '__main__': img = cv2.imread('Fig6.png') cv2.imshow('Fig6', img) b, g, r = cv2.split(img) b = cv2.equalizeHist(b) g = cv2.equalizeHist(g) r = cv2.equalizeHist(r) res = cv2.merge([b, g, r]) cv2.imshow('res', res) if cv2.waitKey(0) & 0xFF == 'q': cv2.destroyAllWindows()
效果:
-
编程实现直方图规定化的处理程序;给定图像Fig7A和图像Fig7B,把Fig7A图像直方图规范化为接近Fig7B图像直方图的分布。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img1 = cv2.imread('Fig7A.jpg')
img2 = cv2.imread('Fig7B.jpg')
img_hsv1 = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV) # bgr转hsv
img_hsv2 = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)
color = ('h', 's', 'v')
for i, col in enumerate(color):
# histr = cv2.calcHist([img_hsv1], [i], None, [256], [0, 256])
hist1, bins = np.histogram(img_hsv1[:, :, i].ravel(), 256, [0, 256])
hist2, bins = np.histogram(img_hsv2[:, :, i].ravel(), 256, [0, 256])
cdf1 = hist1.cumsum() # 灰度值0-255的累计值数组
cdf2 = hist2.cumsum()
cdf1_hist = hist1.cumsum() / cdf1.max() # 灰度值的累计值的比率
cdf2_hist = hist2.cumsum() / cdf2.max()
# 256*256的二维数组
diff_cdf = [[0 for j in range(256)] for k in range(256)] # diff_cdf 里是每2个灰度值比率间的差值
for j in range(256):
for k in range(256):
diff_cdf[j][k] = abs(cdf1_hist[j] - cdf2_hist[k])
lut = [0 for j in range(256)] # 映射表
for j in range(256):
min = diff_cdf[j][0]
index = 0
for k in range(256): # 直方图规定化的映射原理
if min > diff_cdf[j][k]:
min = diff_cdf[j][k]
index = k
lut[j] = ([j, index])
h = int(img_hsv1.shape[0])
w = int(img_hsv1.shape[1])
for j in range(h): # 对原图像进行灰度值的映射
for k in range(w):
img_hsv1[j, k, i] = lut[img_hsv1[j, k, i]][1]
hsv_img1 = cv2.cvtColor(img_hsv1, cv2.COLOR_HSV2BGR) # hsv转bgr
hsv_img2 = cv2.cvtColor(img_hsv2, cv2.COLOR_HSV2BGR)
cv2.namedWindow('firstpic', 0)
cv2.resizeWindow('firstpic', 670, 900)
cv2.namedWindow('targetpic', 0)
cv2.resizeWindow('targetpic', 670, 900)
cv2.namedWindow('defpic', 0)
cv2.resizeWindow('defpic', 670, 900)
cv2.imshow('firstpic', img1)
cv2.imshow('targetpic', img2)
# cv2.imshow('img1', img_hsv1)
cv2.imshow('defpic', hsv_img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果:

实验五
对child.jpg图像的灰度图像进行高通、带通、低通滤波后的结果分别表示彩色图像B、G、R分量。根据颜色分析观察图像中空间频率变化快慢的区域。
import cv2
import numpy as np
from matplotlib import pyplot as plt
if __name__ == '__main__':
index = 30
thre = 10
img_ori = cv2.imread('test.png')
img = cv2.cvtColor(img_ori, cv2.COLOR_BGR2GRAY)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
rows, cols = fshift.shape
rrow = rows // 2
ccol = cols // 2
# 高通
mask1 = np.ones((rows, cols), np.uint8)
mask1[rrow - index: rrow + index, ccol - index: ccol + index] = 0
# 带通
mask2 = np.zeros((rows, cols), np.uint8)
mask2[rrow - index: rrow + index, ccol - index: ccol + index] = 1
mask2[rrow - thre: rrow + thre, ccol - thre: ccol + thre] = 0
# 低通
mask3 = np.zeros((rows, cols), np.uint8)
mask3[rrow - index: rrow + index, ccol - index: ccol + index] = 1
f1 = fshift * mask1
f2 = fshift * mask2
f3 = fshift * mask3
f_ishift1 = np.fft.ifftshift(f1)
f_ishift2 = np.fft.ifftshift(f2)
f_ishift3 = np.fft.ifftshift(f3)
HPF = np.abs(np.fft.ifft2(f_ishift1))
BPF = np.abs(np.fft.ifft2(f_ishift2))
LPF = np.abs(np.fft.ifft2(f_ishift3))
# plt.subplot(321), plt.imshow(img, cmap='gray'), plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(331), plt.imshow(HPF, cmap='gray'), plt.title('HPF'), plt.xticks([]), plt.yticks([])
plt.subplot(332), plt.imshow(BPF), plt.title('BPF'), plt.xticks([]), plt.yticks([])
plt.subplot(333), plt.imshow(LPF, cmap='gray'), plt.title('LPF'), plt.xticks([]), plt.yticks([])
# rgb
ans_img = cv2.merge([HPF, BPF, LPF])
plt.subplot(334), plt.imshow(ans_img.astype('uint8')), plt.title('HBL'), plt.xticks([]), plt.yticks([])
ans_img = cv2.merge([HPF, LPF, BPF])
plt.subplot(335), plt.imshow(ans_img.astype('uint8')), plt.title('HLB'), plt.xticks([]), plt.yticks([])
ans_img = cv2.merge([BPF, HPF, LPF])
plt.subplot(336), plt.imshow(ans_img.astype('uint8')), plt.title('BHL'), plt.xticks([]), plt.yticks([])
ans_img = cv2.merge([BPF, LPF, HPF])
plt.subplot(337), plt.imshow(ans_img.astype('uint8')), plt.title('BLH'), plt.xticks([]), plt.yticks([])
ans_img = cv2.merge([LPF, BPF, HPF])
plt.subplot(338), plt.imshow(ans_img.astype('uint8')), plt.title('LBH'), plt.xticks([]), plt.yticks([])
ans_img = cv2.merge([LPF, HPF, BPF])
plt.subplot(339), plt.imshow(ans_img.astype('uint8')), plt.title('LHB'), plt.xticks([]), plt.yticks([])
plt.show()
效果:
实验六
请独自完成视频图像中蓝色物体的跟踪。请用矩形框在视频中标出给跟踪的目标。
import cv2
import numpy as np
if __name__ == '__main__':
cap = cv2.VideoCapture(0)
while 1:
# 获取每一帧
ret, frame = cap.read()
# 转换到HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# 设定蓝色的阈值
lower_blue = np.array([110, 50, 50])
upper_blue = np.array([130, 255, 255])
# 根据阈值构建掩模
mask = cv2.inRange(hsv, lower_blue, upper_blue)
# 开操作
kernel = np.ones((8, 8), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
xy = np.where(mask == 255)
y = list(xy)[0]
x = list(xy)[1]
x_min, x_max = min(x), max(x)
y_min, y_max = min(y), max(y)
cv2.rectangle(frame, (x_min, y_min), (x_max, y_max), (0, 255, 0), 2)
# mask = cv2.erode(mask, kernel, iterations=1)
# 对原图像和掩模进行位运算
res = cv2.bitwise_and(frame, frame, mask=mask)
# 显示图像
cv2.imshow('frame', frame)
cv2.imshow('mask', mask)
cv2.imshow('res', res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
# 关闭窗口
cv2.destroyAllWindows()
用蓝色瓶盖(如芬达)。效果不好的话需要调整阈值参数和开操作的模板大小。
数字图像处理实验思考题
https://blog.mingchenliu.com/数字图像处理实验思考题/