高斯金字塔和拉普拉斯金字塔
使用函数 cv2.pyrDown(src , dst , dstsize ) 从一个高分辨率大尺寸的图像向上构建一个金子塔(尺寸变小,分辨率降低)
src 输入图
dst 输出图,深度会和来源图相同,尺寸会依输入图参数决定,
dstsize 输出图的尺寸,通常,输出图的尺寸为: Size((src.cols+1)/2,(src.rows+1)/2) )
缩小图像方法原理:
对图像G_i进行高斯内核卷积
将所有偶数行和列去除
img = cv2.imread('op.jpg')
down1 =cv2.pyrDown(img)
down2 =cv2.pyrDown(down1)
cv2.imshow('down1',down1)
cv2.imshow('down2',down2)
cv2.imshow('img',img)
缩小
使用函数 cv2.pyrUp(src ,dst , dstsize) 从一个低分辨率小尺寸的图像向下构建一个金子塔(尺寸变大,但分辨率不会增加)
放大图像方法原理:
将图像在每个方向扩大为原来的两倍,新增的行和列以0填充
使用先前同样的内核(乘以4)与放大后的图像卷积,获得 “新增像素”的近似值
img = cv2.imread('op.jpg')
up =cv2.pyrUp(img)
cv2.imshow('up',up)
cv2.imshow('img',img)
拉普拉斯金字塔可以由高斯金字塔计算得来,公式如下:
img = cv2.imread('op.jpg')
down = cv2.pyrDown(img)
down_up =cv2.pyrUp(down)
la_l = img-down_up
cv2.imshow('la_l',la_l)
图像轮廓
轮廓检测方法
使用函数 cv2.findContours( img ,mode,method)
返回值:contours(轮廓):是一个列表,里面存贮着图像中所有的轮廓,每一个轮廓都是一个numpy数组,包含对象边界点(x, y)的坐标)
hierarchy:轮廓的层析结构
mode :轮廓检索模式
RETR_EXTENAL:只检索最外面的轮廓
RETR_LIST:检索所有轮廓,并保存到一条链表中
RETR_CCOMP:检索所有轮廓并分为两层,外层是各部分外部边界,内层是空洞边界
RETR_TREE:检索所有轮廓,并重构嵌套轮廓的整个层次 (这个用最多)
method:轮廓逼近方法
CHAIN_APPROX_NONE:所有的边界点都会被存储,以Freeman链码方式输出轮廓
CHAIN_APPOX_SIMPLE:压缩轮廓,将轮廓上的冗余点都去掉,只保留终点部分
注:此函数会修改原图,需要copy一个副本。。
轮廓检测结果
把轮廓绘画到图像上
使用函数cv2.drawContours(img, contours, -1, (0,0,255), 2)
传入绘制图像(副本)、轮廓、轮廓索引:-1为所有图像、颜色模式、线条粗细
img = cv2.imread('oc.jpg')
gray =cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret ,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
img1 =img.copy()
res = cv2.drawContours(img1,contours,-1,(0,0,255),2)
cv2.imshow('img1',res)
轮廓特征与近似
轮廓面积:使用函数 cv2.contourArea()
cnt = contours[-1]
area = cv2.contourArea(cnt)
print(area)
轮廓周长:使用函数 cv2.arcLength()
这个函数第二参数可以用来指定对象的形状是闭合的(True),还是打开的(一条曲线)
cnt = contours[-1] #可以单独索引
perimeter = cv2.arcLength(cnt,True)
print(perimeter)
轮廓近似
原理:
使用函数 cv2.approxPolyDP(cnt,epsilon,True)
cnt :传入轮廓
epsilon :从原始轮廓到近似轮廓的最大距离,它是一个准确度参数(一般用周长的百分比)
img = cv2.imread('od.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = contours[-1] #一个轮廓0就行,这里有其他微小轮廓用了-1
#绘制独立轮廓
img1 = img.copy()
img2 = img.copy()
img1 = cv2.drawContours(img1,[cnt],-1,(0,0,255),3)
epsilon = 0.01*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
img2 = cv2.drawContours(img2,[approx],-1,(0,0,255),3)
res = np.hstack((img1,img2))
cv2.imshow('img',res)
边界矩形
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
最小外接圆
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,255,0),2)