实验六:数学形态及图像压缩
实验目标:
- Python
- 小波变换及多分辨率处理相关知识。
实验要求:
- 图像压缩:对imgs目录下的图像进行图像压缩测试,调节参数查看效果。 实验图片路径为:
imgs/1.jpg
imgs/2.jpg
imgs/3.jpg
输出路径为:outputs/ - 形态学操作:尝试使用形态学操作的方法提取图片morphology.jpg中的国旗图案。
实验图片路径为:
imgs/morphology.jpg
输出路径为:outputs/
实验方案:
-
图像压缩:
a. 首先导入了PIL库中的Image模块、os模块以及opencv库中的cv2模块。
b. 通过两层循环,分别遍历压缩质量quality(0, 25, 50, 75, 100)和三张图片(编号为1、2、3)。c. 在每次循环中,构建输入图片的路径input_path,其中包含当前循环中的图片序号。
d. 使用cv2.imread()函数读取对应路径的图片,并将其赋值给img变量。
e. 调用cv2.imwrite()函数,将处理后的图片以JPEG格式保存到指定路径,路径中包含图片序号和压缩质量。其中[cv2.IMWRITE_JPEG_QUALITY, quality]参数表示设置JPEG图像的压缩质量。
f. 同样使用cv2.imwrite()函数,将处理后的图片以JPEG2000格式保存到另一个指定路径,路径中同样包含图片序号和压缩质量。这里使用了参数[cv2.IMWRITE_JPEG2000_COMPRESSION_X1000, quality]来设置JPEG2000图像的压缩质量。
from PIL import Image
import os
import cv2
for quality in range(0,101,25):
for i in range(3):
input_path=r'C:\Users\LCX\Documents\imgs\imgs\{}.jpg'.format(i+1)
img=cv2.imread(input_path,1)
cv2.imwrite(r'C:\Users\LCX\Documents\outputs\6\6_1_{}_{}.jpg'.format(i+1,quality),img,[cv2.IMWRITE_JPEG_QUALITY,quality])
cv2.imwrite(r'C:\Users\LCX\Documents\outputs\6\6_1_{}_{}.jp2'.format(i+1,quality),img, [cv2.IMWRITE_JPEG2000_COMPRESSION_X1000, quality])
-
形态学操作:
a. 导入必要的库import cv2 import numpy as np
b. 读取图像并创建一个副本
image=cv2.imread(r'C:\Users\LCX\Documents\imgs\morphology.jpg') imagetemp = image.copy()
c. 寻找白色区域并替换为红色,然后进行灰度化和二值化处理
# 寻找白色区域 white_mask = cv2.inRange(image, lower_white, upper_white) # 将白色替换为红色 image[white_mask > 0] = [0, 0, 255] # 灰度化 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 二值化 imgbina, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
d. 对二值化图像进行腐蚀和膨胀操作
kernel = np.ones((3, 3), np.uint8) eroded_edges = cv2.erode(binary, kernel, iterations=1) dilated_image = cv2.dilate(eroded_edges, kernel, iterations=2) eroded_edges = cv2.erode(dilated_image, kernel, iterations=1)
e. 边缘检测和轮廓检测
edges = cv2.Canny(eroded_edges, 50, 150) contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
f. 筛选符合条件的轮廓并记录
flag_contours = [] for contour in contours: #计算周长 perimeter = cv2.arcLength(contour, True) #近似多边形操作 approx = cv2.approxPolyDP(contour, 0.02 * perimeter, True) #边数为4,则为矩形 if len(approx) == 4: flag_contours.append(approx)
f. 截取矩形区域并保存
for i, contour in enumerate(flag_contours): x, y, w, h = cv2.boundingRect(contour) if w > 45 and w < 52 and h > 30 and h < 35: roi = imagetemp[y:y+h, x:x+w] outpath = r'C:\Users\LCX\Documents\outputs\flags\rectangle_{}.jpg'.format(i+1) cv2.imwrite(outpath, roi)
g. 对副本图像进行灰度化和二值化处理,然后进行圆检测
graytemp = cv2.cvtColor(imagetemp, cv2.COLOR_BGR2GRAY) _, binarytemp = cv2.threshold(graytemp, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) circles = cv2.HoughCircles(binarytemp, cv2.HOUGH_GRADIENT, dp=1, minDist=115, param1=1529, param2=8, minRadius=23, maxRadius=23) if circles is not None: circles = np.uint16(np.around(circles)) for i in circles[0, :]: center = (i[0], i[1]) radius = i[2] x = center[0] - radius y = center[1] - radius w = h = 2 * radius roi = imagetemp[y:y+h, x:x+w] cv2.imwrite(r'C:\Users\LCX\Documents\outputs\circles\circle_roi{}.jpg'.format(i), roi)
实验结果:
- 图像压缩
图 1 使用jpeg2000格式压缩图1,质量取0,25,50,75,100
图 2 使用jpeg2000格式压缩图2,质量取0,25,50,75,100
*图 3 使用jpeg2000格式压缩图3,质量取0,25,50,75,100
图 4 使用jpg格式压缩图1,质量取0,25,50,75,100
图 5 使用jpg格式压缩图2,质量取0,25,50,75,100
图 6 使用jpg格式压缩图3,质量取0,25,50,75,100
- 形态学操作
图7 提取的圆形旗帜
图8 提取的矩形旗帜
实验总结:
-
图像压缩部分:
- 在图像压缩实验中,通过调节不同的压缩质量参数,对三张图片进行了JPEG和JPEG2000格式的压缩处理。观察到随着压缩质量的减少,图片的清晰度逐渐下降,同时文件大小也在相应地减小。
- 通过这个实验可以更直观地感受到不同压缩质量、不同压缩方式对图像质量和文件大小的影响。
- JPG基于离散余弦变换(DCT)的压缩技术。在较低的压缩比下,JPG的图像质量可能优于JPEG2000。但在高压缩比下,JPEG2000的压缩性能开始显现优势,其压缩率比JPG高约30%左右。JPEG2000的失真主要是模糊失真,而JPG则可能出现块状模糊瑕疵。
- JPEG2000:基于小波变换(Wavelet Transform)的压缩技术。JPEG2000在压缩性能上优于JPG。特别是在高压缩比下,JPEG2000的图像质量仍然可以保持相对较高的水平。
-
形态学操作部分:
- 在形态学操作实验中,首先对输入图像进行了预处理,包括寻找白色区域、替换颜色、灰度化和二值化处理。
- 然后利用腐蚀和膨胀操作对二值化图像进行了处理,平滑了旗帜的边界,最终通过边缘检测和轮廓检测找到符合条件的矩形轮廓并截取保存。
- 对副本图像进行了类似的处理,并进行了圆检测操作,提取出圆形区域并保存。
- 提取矩形时通过预先将白色替换为与背景对比更明显的红色可以更好地提取白色部分占比较高的旗帜。