应该记住的是图像的宽对应的是列数,高对应的是行数。
读取图片
import cv2 as cv
import sys
from matplotlib import pyplot as plt
img=cv.imread('bg.jpg',-1) # -1 是彩色图片
#img=cv.imread('bg.jpg',0) #0 是 灰度图片
#img=cv.imread(cv.samples.findFile("C:/Users/Administrator/Desktop/bg.jpg"))
img=cv.resize(img,(640,480))
if img is None:
sys.exit("no this img!")
#cv.namedWindow('img',cv.WINDOW_NORMAL)
img=cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.imshow("img",img)
if cv.waitKey(0)& 0xff==ord('q'):
cv.destroyAllWindows()
elif cv.waitKey(0)& 0xff==ord('s'):
cv.imwrite("C:/Users/Administrator/Desktop/save.jpg",img)
cv.destroyAllWindows()
读摄像头
import cv2 as cv
import sys
cap=cv.VideoCapture(0)
cap.set(3,640)
cap.set(4,480)
if not cap.isOpened():
sys.exit("no camera!")
ret,frame=cap.read()
while (ret):
ret,frame=cap.read()
gray=frame.copy()
gray=cv.cvtColor(gray, cv.COLOR_BGR2GRAY)
if ret:
cv.imshow('img',frame)
cv.imshow('gray',gray)
if cv.waitKey(1) & 0xff ==ord('q'):
break
cap.release()
cv.destroyAllWindows()
录摄像头视频
import cv2 as cv
import sys
cap=cv.VideoCapture(0)
fourcc=cv.VideoWriter_fourcc(*'XVID')
out=cv.VideoWriter('out.avi',fourcc,25,(640,480))
while(cap.isOpened()):
ret,frame=cap.read()
if ret:
out.write(frame)
cv.imshow('img',frame)
if cv.waitKey(1) &0xff ==ord('q'):
break
cap.release()
cv.destroyAllWindows()
绘画
import cv2 as cv
import numpy as np
bg=np.zeros((640,480,3),dtype=np.uint8)
font=cv.FONT_HERSHEY_SIMPLEX
cv.rectangle(bg,(0,0),(255,255),(0,0,255),-1,lineType=cv.LINE_AA)
cv.line(bg,(255,255),(480,480),(0,255,255),2,lineType=cv.LINE_AA)
cv.putText(bg,'hello world!',(255,260),font,1,(255,255,255),5)
cv.imshow('line',bg)
cv.waitKey(0)
cv.destroyAllWindows()
几何变换
扩展缩放,只改变图像的尺寸大小
应该记住的是图像的宽对应的是列数,高对应的是行数。
INTER_NEAREST | 最近邻插值
INTER_LINEAR | 双线性插值(默认设置)
INTER_AREA | 使用像素区域关系进行重采样
INTER_CUBIC | 4x4像素邻域的双三次插值
INTER_LANCZOS4 | 8x8像素邻域的Lanczos
import cv2
import numpy as np
def cv_show(name,img):
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
img=cv2.imread('knife.jpg')
rows,cols,_=img.shape
M=np.float32([[1,0,100],[0,1,100]]) #create the move matrix x move left 100 and y move down 100 pixel
move=cv2.warpAffine(img,M,(cols,rows)) # the size of output tip:(cols,rows)
cv_show('move',move)
M=cv2.getRotationMatrix2D((rows/2,cols/2),45,1)
rotation=cv2.warpAffine(img,M,(cols,rows))
cv_show('rotation',rotation)
points1=np.float32([[100,50],[100,200],[300,50]]) # affine
points2=np.float32([[150,100],[150,250],[350,100]])
M=cv2.getAffineTransform(points1,points2)
affine=cv2.warpAffine(img,M,(cols,rows))
cv_show('affine',affine)
pts1=np.float32([[100,50],[100,200],[300,50],[300,200]]) # perspective
pts2=np.float32([[150,100],[150,250],[350,100],[350,250]])
M=cv2.getPerspectiveTransform(pts1,pts2)
perspective=cv2.warpPerspective(img,M,(cols,rows))
cv_show('per',perspective)
全局阈值与位计算
掩膜
bg.jpg cvlogo.JPG
from matplotlib import pyplot as plt
import cv2 as cv
import numpy as np
img=cv.imread(cv.samples.findFile('bg.jpg'))
logo=cv.imread(cv.samples.findFile('cvlogo.JPG'))
rows,cols,channels=logo.shape
roi=img[200:200+rows,200:200+cols]
logogray=cv.cvtColor(logo, cv.COLOR_BGR2GRAY)
ret,mask=cv.threshold(logogray, 27, 255, cv.THRESH_BINARY)
mask_inv=cv.bitwise_not(mask)
roi_bg=cv.bitwise_and(roi, roi,mask=mask_inv)
logo_bg=cv.bitwise_and(logo,logo,mask=mask)
result=cv.add(roi_bg, logo_bg)
img[200:200+rows,200:200+cols]=result
cv.imshow('img',roi_bg)
cv.imshow('logo',logo_bg)
cv.imshow('res',img)
cv.waitKey(0)
cv.destroyAllWindows()
使用自适应阈值:当同一幅图像上的不同部分具有不同亮度时
import cv2 as cv
from matplotlib import pyplot as plt
import numpy as np
img=cv.imread('bg.jpg')
a=cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,blockSize=11,c=2)
#blocksize 邻域大小 C 常数 cv.ADAPTIVE_THRESH_MEAN_C 阈值取相邻区域的平均值
b=cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,blockSize=11,c=2)
#cv.ADAPTIVE_THRESH_GAUSSIAN_C 阈值取相邻区域的加权和,权重为一个高斯窗口
ret2,th2 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
#在使用全局阈值时,我们就是随便给了一个数来做阈值,那我们怎么知道我们选取的这个数的好坏呢?答案就是
#不停的尝试。如果是一副双峰图像(简单来说双峰图像是指图像直方图中存在两个峰)呢?我们岂不是应该在两
#个峰之间的峰谷选一个值作为阈值?这就是Otsu 二值化要做的。简单来说就是对一副双峰图像自动根据其直方
#图计算出一个阈值。(对于非双峰图像,这种方法得到的结果可能会不理想)
plt.hist(img.ravel(),256) # plt.hist, 要注意的是它的参数是一维数组
# 所以这里使用了(numpy)ravel 方法,将多维数组转换成一维,也可以使用flatten 方法
plt.imshow()
图像平滑/图像模糊(2D卷积)
使用低通滤波器可以达到图像模糊的目的。这对与去除噪音很有帮助。其实就是去除图像中的高频成分(比如:噪音,边界)。所以边界也会被模糊一点。(当然,也有一些模糊技术不会模糊掉边界)
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
#img=Image.open('bg.jpg')
img=cv.imread('bg.jpg')
img=cv.cvtColor(img,cv.COLOR_BGR2RGB)
kernel=np.ones((5,5),dtype=np.float32)/25
out=cv.filter2D(img,-1,kernel) #-1 表示图片深度和原图像一样
plt.subplot(121),plt.imshow(img),plt.title('img')
plt.subplot(122),plt.imshow(out),plt.title('out')
plt.xticks([]),plt.yticke([])
p