一、创建显示窗口图片
namedWindow() #命名窗口
imshow(name, img) #显示图片(name表示窗口的名称,img表示要显示的图片)
destroyAllwindows() #摧毁窗口
resizeWindow() #重设窗口大小
waitKey() #等待用户输入
imread() #读取图像 #读取的图像为np.array
imwrite() #图像的保存
resize(img,(wide,high),cv2.INTER_LINEAR) #重设图片大小
切片操作实现图片翻转和颜色变化:
img[:,:,::-1] #表示rgb波段翻转,红色变蓝色
img[:,:,[0,2,1]] #rgb变成rbg
img[::-1,:,:] #表示图片上下翻转
img[:,::-1,:] #表示左右翻转
二、画图形
cv2.line() #画线
cv2.rectangle() #画矩形
cv2.circle() #画圆
cv2.ellipse(img,中心点坐标,长轴和短轴,角度,开始角,结束角,颜色,线宽,去毛边) #画椭圆
三、绘制文本
cv2.putText()在指定位置绘制文本,只能绘制数字和英文,不能绘制中文;绘制中文要使用外部库pillow
from PIL import ImageFont,Image,ImageDraw
#绘制文本
font = ImageFont.truetype('./msyhbd.ttc',50)
img_pil = Image.fromarray(img)
draw = ImageDraw.Draw(img_pil)
draw.text((280,270),'炎柱 V',font=font,fill=(0,0,255))
draw.text((450,270),'S 上弦之叁',font=font,fill=(255,255,0))
#再转回到array
img = np.array(img_pil)
现象如下:
四、获取摄像头并显示(人脸检测为例)
#使用opencv提供的人脸识别器
face_detector = cv2.CascadeClassifier('./haarcascade_frontalface_alt.xml')
cap = cv2.VideoCapture(0) #捕获摄像头
#无限循环显示图片,达到动态效果
while True:
ret,frame = cap.read()
#图像灰度处理,达到数据压缩的效果
gray_img = cv2.cvtColor(frame,code=cv2.COLOR_BGR2GRAY)
#用人脸识别器识别人脸,返回人脸的左上角坐标以及长度和宽度
faces = face_detector.detectMultiScale(gray_img)
#将每个人脸框出来
for x,y,w,h in faces:
cv2.rectangle(frame,(x,y),(x+w,y+h),[0,0,255],3)
cv2.imshow('video',frame)
key = cv2.waitKey(1000//50)#每秒读取50帧图像
if key == ord('q'):#检测到空格退出
break
五、图像马赛克
#图片马赛克,如果要对其中的一部分马赛克,切片操作即可
'''图片缩小再放大,相当于模糊处理'''
img1 = cv2.resize(img,(img.shape[1]//20,img.shape[0]//20),interpolation=cv2.INTER_LINEAR)
img2 = cv2.resize(img1,(img1.shape[1]*20,img1.shape[0]*20),interpolation=cv2.INTER_LINEAR)
show_image('draw',img2)
'''先将图片缩小,再将每个像素点在长宽两个维度上复制,在显示'''
img3 = np.repeat(img1,20,axis=0)
img3 = np.repeat(img3,20,axis=1)
show_image('draw',img3)
'''每隔20个点取一个点,再复制'''
img4 = img[::20,::20,:]
img4 = np.repeat(img4,20,axis=0)
img4 = np.repeat(img4,20,axis=1)
show_image('draw',img4)
现象如下图:
六、图像边缘提取
(1)使用cv2.Canny()函数,提取出完整的轮廓
img5 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img6 = cv2.GaussianBlur(img5,(3,3),0) #高斯模糊,会使图片模糊但也会使图片平滑
#越平滑边缘越不清晰
img7 = cv2.Canny(img6,75,200) #边缘检测函数,检测出边缘
show_image('edge',img7)
现象如下:
(2)使用cv2.findContours()函数,提取出每一层轮廓
gray = cv2.cvtColor(img_dragon,code = cv2.COLOR_BGR2GRAY)
#图像二值化,非黑即白(超过100为白,低于100为黑),处理灰度图
__,binary = cv2.threshold(gray,100,255,cv2.THRESH_OTSU)
#边缘检测,返回轮廓点和轮廓之间的关系
counters,hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#按照面积大小进行排序
areas = []
for counter in counters:
areas.append(cv2.contourArea(counter))
areas = np.asarray(areas)
#按照面积进行排序,返回索引
index = areas.argsort()
print(len(index))
mask = np.zeros_like(gray,dtype=np.uint8)
#绘制轮廓绘制了倒数第二层轮廓
mask = cv2.drawContours(mask,counters,index[-2],(255, 255, 255), -1)
七、人脸贴纸画
faces = face_dector.detectMultiScale(img_child)
for x,y,w,h in faces:
mask2 = cv2.resize(mask,(w,h))
#黑白转换
mask3 = (mask2-255)*255
#用按位与或者按位或来取,需要设置好mask,较难理解
img_dragon2 = cv2.resize(img_dragon,(w,h))
child_face = img_child[y:y+h,x:x+w]
face2 = np.zeros_like(child_face,dtype=np.uint8)
img_dragon3 = cv2.bitwise_and(img_dragon2,img_dragon2,mask=mask2)
face3 = cv2.bitwise_and(child_face,child_face,mask=mask3)
face = cv2.bitwise_or(img_dragon3,face3)
img_child[y:y + h, x:x + w] = face
#for 循环将人脸换成我们所设定的图案
for x,y,w,h in faces:
mask2 = cv2.resize(mask,(w,h))
img_dragon2 = cv2.resize(img_dragon,(w,h))
for i in range(h):
for j in range(w):
if (mask2[i,j] == 255).all():
img_child[i+y,j+x] = img_dragon2[i,j]
八、图片直方图均衡化
import cv2
from skimage import data
import matplotlib.pyplot as plt
img = cv2.imread('../image/mohu.jpg')
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imshow('moon',img)
#直接画出灰度直方图
plt.hist(img.ravel(),bins=256)
plt.show()
#灰度直方图均衡化,使图片变得层次分明
img2 = cv2.equalizeHist(img)
plt.hist(img2.ravel(),bins=256)
plt.show()
cv2.imshow('moon',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
现象如下图所示: