[Computer Vision]实验一:图像的基本操作
目录
一、实验内容
二、实验代码
2.1 实验源码
2.2 实验结果
一、实验内容
- 分别使用PIL库和OpenCV库读取图像并实现可视化、调整图像大小、图像掩模等,对比OpenCV读取和PIL读取的差异;
- 绘制图像的轮廓与直方图;
- 实现图像的灰度变换、直方图均衡化;
- 实现图像的不同高斯模糊、计算导数;
- 形态学计数(计算圆形个数等)、去噪;
- 实现数字水印
二、实验代码
2.1 实验源码
2.1.1 PIL库、OpenCV库处理图像
def PIL_image(imgsrc):
image=Image.open(imgsrc)
image.show()
width=500
height=500
new_size=(width,height)
resized_image=image.resize(new_size)
resized_image.show()
mask=Image.new("L",image.size,0)
draw=ImageDraw.Draw(mask)
draw.rectangle([50,50,200,200],fill=255)
result_img=Image.new("RGBA",image.size)
result_img.paste(image,mask=mask)
result_img.show()
plt.figure("Original and new Images")
plt.subplot(2,2,1)
plt.imshow(image)
plt.title("Original Image")
plt.subplot(2,2,2)
plt.imshow(resized_image)
plt.title("Resized Image")
plt.subplot(2,2,3)
plt.imshow(result_img)
plt.title("draw mask")
plt.show()
def opencv_image(imgsrc):
image=cv2.imread(imgsrc)
cv2.imshow('img',image)
width=320
height=500
new_size=(width,height)
resized_image=cv2.resize(image,new_size,interpolation=cv2.INTER_AREA)
cv2.imshow('resized img',resized_image)
mask=np.zeros(image.shape[:2],dtype="uint8")
cv2.rectangle(mask,(50,50),(200,200),255,-1)
result_img=cv2.bitwise_and(image,image,mask=mask)
cv2.imshow('draw mask',result_img)
cv2.waitKey()
cv2.destroyAllWindows()
plt.figure("Original and new Images")
plt.subplot(2,2,1)
plt.imshow(image)
plt.title("Original Image")
plt.subplot(2,2,2)
plt.imshow(resized_image)
plt.title("Resized Image")
plt.subplot(2,2,3)
plt.imshow(result_img)
plt.title("draw mask")
plt.show()
2.1.2 绘制图像轮廓和灰度图
def drawoutlines(imgsrc):
image=cv2.imread(imgsrc)
gray_img=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
_,threshold=cv2.threshold(gray_img,127,255,cv2.THRESH_BINARY)
contours,_=cv2.findContours(threshold,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(image,contours,-1,(0,255,0),2)
cv2.imshow('Image with Outlines',image)
cv2.waitKey(0)
cv2.destroyAllWindows()
def draw_hist(imgsrc):
image=cv2.imread(imgsrc)
gray_img=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
histogram=cv2.calcHist([gray_img],[0],None,[256],[0,256])
cv2.imshow('Original img',image)
cv2.imshow('Gray img',gray_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
plt.figure()
plt.title("draw histogram")
plt.xlabel("Grayscale")
plt.ylabel("pixel ")
plt.plot(histogram)
plt.xlim([0,256])
plt.show()
2.1.3 直方图均衡化
def equlize_Hist(imgsrc):
image=cv2.imread(imgsrc)
gray_img=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
equ_img=cv2.equalizeHist(gray_img)
histogram=cv2.calcHist([gray_img],[0],None,[256],[0,256])
equa_hist=cv2.calcHist([equ_img],[0],None,[256],[0,256])
cv2.imshow('Original img',image)
cv2.imshow('Gray img',gray_img)
cv2.imshow('EqualizeHist img',equ_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
plt.figure()
plt.subplot(1,2,1)
plt.title("Original histogram")
plt.xlabel("Grayscale")
plt.ylabel("pixel ")
plt.plot(histogram)
plt.xlim([0,256])
plt.subplot(1,2,2)
plt.title("EqualizedHist")
plt.xlabel("Grayscale")
plt.ylabel("pixel")
plt.plot(equa_hist)
plt.xlim([0,256])
plt.show()
2.1.4 高斯模糊、计算导数
def Gauss_process(imgsrc):
image=cv2.imread(imgsrc)
Gauss_img=cv2.GaussianBlur(image,(7,7),0)
x_sobel=cv2.Sobel(image,cv2.CV_64F,1,0,ksize=3)
x_sobel=cv2.convertScaleAbs(x_sobel)
y_sobel=cv2.Sobel(image,cv2.CV_64F,0,1,ksize=3)
y_sobel=cv2.convertScaleAbs(y_sobel)
#magnitude=np.sqrt(np.square(x_sobel)+np.square(y_sobel))
magnitude=np.sqrt(0.5*x_sobel+0.5*y_sobel)
magnitude = np.uint8(magnitude)
magnitude = np.uint8(cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX))
print("x方向"+"\n"+str(x_sobel))
print("y方向"+"\n"+str(y_sobel))
print("梯度幅值"+"\n"+str(magnitude))
cv2.imshow('Original Image',image)
cv2.imshow('Blurred Image',Gauss_img)
cv2.imshow('X',x_sobel)
cv2.imshow('Y',y_sobel)
cv2.imshow('XY',magnitude)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.1.5 心态学计数
def countcircles(imgsrc):
min_radius=100
max_radius=200
image=cv2.imread(imgsrc)
gray_img=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
Gauss_img=cv2.GaussianBlur(gray_img,(5,5),0)
circles=cv2.HoughCircles(Gauss_img,cv2.HOUGH_GRADIENT,1,20,param1=40,param2=60,minRadius=min_radius,maxRadius=max_radius)
if circles is not None:
circles=np.uint16(np.around(circles))
for i in circles[0,:]:
cv2.circle(image,(i[0],i[1]),i[2],(0,255,0),2)
cv2.circle(image,(i[0],i[1]),2,(0,0,255),3)
cv2.imshow('circles image',image)
cv2.waitKey(0)
cv2.destroyAllWindows()
return len(circles[0,:])
else:
return 0
2.1.6数字水印
def add_watermark(imgsrc1,imgsrc2):
image=cv2.imread(imgsrc1)
watermark=cv2.imread(imgsrc2)
watermark_alpha = 0.3
image_with_watermark = cv2.addWeighted(image, 1 - watermark_alpha, watermark, watermark_alpha, 0)
cv2.imshow('Image with Watermark', image_with_watermark)
cv2.waitKey(0)
cv2.destroyAllWindows()
main函数
import cv2
from PIL import Image,ImageDraw
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
imgsrc="D:/Computer vision/picture1.png"
imgsrc1="D:/Computer vision/picture3.png"
imgsrc2="D:/Computer vision/picture2.png"
imgsrc3="D:/Computer vision/picture4.png"
PIL_image(imgsrc)
opencv_image(imgsrc)
drawoutlines(imgsrc1)
draw_hist(imgsrc1)
equlize_Hist(imgsrc)
Gauss_process(imgsrc)
count_cir=countcircles(imgsrc2)
print("图片中圆形个数:",count_cir)
add_watermark(imgsrc1,imgsrc3)
2.2 实验结果
2.2.1 对比OpenCV读取和PIL读取的差异
(1)使用PIL库,通过使用Image.open()函数读取图像,通过image.show()实现可视化;通过Image.resize()函数调整图像大小;创建一个新RGBA图像,将原始图像粘贴到该图像上,同时应用mask(与原始图像大小相同的透明图像,图像中绘制了一个矩形区域)实现图像掩模。结果图如下:
(2)使用opencv库,通过cv2.imread()函数读取图像;通过cv2.imshow()函数实现可视化;通过cv2.resize()函数实现调整图像大小;通过cv2.bitwise_and()函数将原始图像与mask进行按位与操作实现图像掩模。结果图如下:
OpenCV读取的图像默认为NumPy数组,数据类型为uint8(无符号8位整数),范围从0到255。而PIL读取的图像默认为PIL.Image对象,数据类型为uint8。
2.2.2 使用opencv库绘制图像的轮廓和直方图的结果如下:
(1)绘制轮廓时,将读取的彩色图像转换为灰度图像,再应用阈值处理,将灰度图像转换为二值图像,使用cv2.findContours()函数在二值化图像中找到轮廓,只检测外部轮廓(cv2.RETR_EXTERNAL),并使用简化的方cv2.CHAIN_APPROX_SIMPLE来存储轮廓信息,结果存储在变量contours中。最后在原始图像上绘制轮廓并显示出来。
(2)绘制图像的直方图时,将彩色图像转换为灰度图像,通过cv2.calcHist()函数计算灰度图像的直方图,参数分别为:输入图像、通道列表、掩码、直方图的大小、灰度值的范围,再使用matplotlib.pyplot绘制直方图。
2.2.3 实现图像灰度变换、直方图均衡化
将彩色图像转换为灰度图像,输出灰度直方图以及均衡化后的直方图。
2.2.4 实现图像的不同高斯模糊、计算导数
通过使用cv2.GaussianBlur()函数对彩色图像image进行高斯模糊处理,其中,参数image是输入图像,参数(ksize,ksize)矩阵[代码中为(7,7)]为高斯核的大小,参数ksize为奇数,参数sigma为高斯核函数的标准差,当sigma为0时,opencv自动计算合适的标准差。
2.2.5 形态学计数(计算圆形个数)、去噪
通过min_radius和max_radius分别设置检测圆的最小半径和最大半径,其中min_radius=100,max_radius=200;将彩色图像转换为灰度图像,对灰度图像进行高斯模糊处理,以减少噪声,通过cv2.HoughCircles函数检测图像中的圆,其中,参数param1=40,param2=60;在原始图像上画出检测到的圆、圆心并显示、输出检测到圆的数量。
2.2.6 数字水印
通过读取两张图片,使用cv2.addWeighted()函数将水印图片添加到原图片上。这个函数的参数分别是:原图片、原图片的权重、水印图片、水印图片的权重(水印透明度)、可选的标量值(0)。最后显示带水印的图片。