Opencv python从零开始第一天之图像轮廓处理

Opencv Python 轮廓处理

Opencv python从零开始第一天之图像轮廓处理

本人大一数学系学渣菜鸟一枚,由于兴趣,课程之余在学习OpenCV,
也是从零开始,想一边学一边把学的东西整理放在CSDN存一下
不喜勿喷哈哈哈哈
我是菜鸡

`

``python
#program 1.绘制轮廓
import numpy as np
import cv2 as cv 
#读取图像
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
#一些必要的操作:导入图像、二值化、canny边缘检测、cnt的给出
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
#创建3*3的高斯滤波内核
img_gray = cv.GaussianBlur(img_gray, (3, 3), 0)
# canny边缘检测
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0] 
#进行绘制
cv.drawContours(img, contours, -1, (0,255,0), 3)
cv.imshow("read", img)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows() 
#program 2.去除图像的矩形边框,找到并提取指定轮廓
#由于图像在识别轮廓的过程中可能会把外框矩形也识别并画出来,所以我们找个办法把指定的轮廓去除
import numpy as np
import cv2 as cv 
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0] 
M = cv.moments(cnt)

cv.imshow("thresh", thresh)
'''    
finContours(img, mode, method)
mode(轮廓检索模式): 
RETR_EXTERNAL :只检索最外面的轮廓; 
RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中;
RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
RETR_TREE(最常用):检索所有的轮廓,并重构嵌套轮廓的整个层次;

method(轮廓逼近方法):
CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。 
CHAIN_APPROX_SIMPLE(最常用):压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
'''
# 查看轮廓的数量
number = numpy.array(contours).shape
# 复制图像,新的图像作为边界绘制的底图
cp = img.copy() 
res1 = cv.drawContours(cp, contours, -1, (0, 0, 255), 2)
cp = img.copy()
res2 = cv.drawContours(cp, contours, 0, (0, 0, 255), 2)
# 合并两张图像
res = numpy.hstack((res1, res2))
print("number:", number)
cv.imshow("res", res)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#program 3.提取特征矩,进行简单计算
'''
关于图像的矩的一些解析:
矩用来抽取图像(块)特征,本质上,Hu矩其实就是泰勒级数展开的对应项。其他类型的矩也是对应多项式展开的级数(如Legendre矩对应Legendre级数)。在图像里,低阶矩反映低频(主要的)信息,高阶矩反映高频(细节)信息,
0阶矩( m[00]):目标区域的面积(Area)
1阶矩( m[01] , m[10] ):目标区域的质心(Centroid)
以目标区域的质心为中心构建中心矩,那么矩的计算时永远是目标区域中的点相对于目标区域的质心,而与目标区域的位置无关,即中心矩具备了平移不变性。
2阶矩(m[20] ,m[02] , m[11] ):即惯性矩,可计算目标图像的方向
3阶矩(m[30] , m[03] , m[12], m[21]):目标区域的方位和斜度,反应目标的扭曲
Hu矩:目标区域往往伴随着空间变换(平移,尺度,旋转),所以需要在普通矩的基础上构造出具备不变性的矩组

更多关于矩的知识可以参考https://www.cnblogs.com/ronny/p/3985810.html


'''
import numpy as np
import cv2 as cv 
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0] 
M = cv.moments(cnt)
#求图像面积
area = cv.contourArea(cnt)
#求图像周长
perimeter = cv.arcLength(cnt,True)
#第二参数可以用来指定对象的形状是闭合的(True)还是打开的(一条曲线)
print(perimeter)
print( M )
print(area)
#program 4.轮廓近似
import numpy as np
import cv2 as cv 
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
#参数设置
epsilon = 0.1*cv.arcLength(cnt,True)
approx = cv.approxPolyDP(cnt,epsilon,True)# 第三个函数参数若为true,则说明近似曲线是闭合的,它的首位都是相连,反之,若为false,则断开。
cv.imshow('approx',img)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#program 5.凸包
import numpy as np
import cv2 as cv 
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
img_result = img.copy()
#获取连通域
cont = get_contours(img_src)
cv.drawContours(img_result, cont, -1, (0, 0, 255), 2)
#获取凸包点,连接点
hull_points = cv.convexHull(cont)#检查一个曲线的凸性缺陷并进行修正
cv.polylines(img_result, [hull_points], True, (0, 255, 0), 2)
cv.imshow("img_result", img_result)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows() 
#program 6.规则图形的拟合:矩形、旋转矩形、圆、椭圆
import numpy as np
import cv2 as cv 
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
x,y,w,h = cv.boundingRect(cnt)
#拟合矩形
img1 = cv.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv.imshow("rectangle", img1)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows() 
#拟合旋转矩形
rect = cv.minAreaRect(cnt)
box = cv.boxPoints(rect)
box = np.int0(box)
img2 = cv.drawContours(img,[box],0,(0,0,255),2)
cv.imshow("rotarec", img2)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#拟合图像轮廓的最小闭合圈
(x,y),radius = cv.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)#取整
img3 = cv.circle(img,center,radius,(0,255,0),2)
cv.imshow("rectangle", img3)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#拟合图像轮廓的最小闭合椭圆
ellipse = cv.fitEllipse(cnt)
img4 = cv.ellipse(img,ellipse,(0,255,0),2)
cv.imshow("rectangle", img4)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#program 7.轮廓属性的提取与运用
import numpy as np
import cv2 as cv 
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
x,y,w,h = cv.boundingRect(cnt)
area = cv.contourArea(cnt)
#求轮廓的长宽比
aspect_ratio = float(w)/h
print(aspect_ratio)
#求轮廓的范围:轮廓区域与边界区域比值 
rect_area = w*h
extent = float(area)/rect_area
print(extent)
#求轮廓的坚实度:等高线面积与其凸包面积之比
hull = cv.convexHull(cnt)
hull_area = cv.contourArea(hull)
solidity = float(area)/hull_area
print(solidity)
#求轮廓的等效直径:面积与轮廓面积相同的圆的直径
equi_diameter = np.sqrt(4*area/np.pi)
print(equi_diameter)
#求轮廓的取向:物体指向的角度
(x,y),(MA,ma),angle = cv.fitEllipse(cnt)
#MA为主轴长度,ma为负轴长度
print(MA)
print(ma)
print(angle)
#找到构成对象的所有点
mask = np.zeros(img_gray.shape,np.uint8)
cv.drawContours(mask,[cnt],0,255,-1)
pixelpoints = cv.findNonZero(mask)
#可以用numpy的  pixelpoints = np.transpose(np.nonzero(mask)) 来替换这一句
print(pixelpoints)
#找到这些点的最大值,最小值和它们的位置
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(img_gray,mask = mask)
print(min_val)
print(max_val)
print(min_loc)
print(max_loc)
#program 8.找到对象的平均颜色或灰值图像的平均强度
import numpy as np
import cv2 as cv 
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
mean_val = cv.mean(img,mask = mask)
print(mean_val)
#program 9.找到图像的极端点
import numpy as np
import cv2 as cv 
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])
print(leftmost,rightmost,topmost,bottommost)
#program 10.修正凸性缺陷
import numpy as np
import cv2 as cv 
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
ret, thresh = cv.threshold(cv.cvtColor(img.copy(), cv.COLOR_BGR2GRAY) , 127, 255, cv.THRESH_BINARY)
black = cv.cvtColor(np.zeros((img.shape[1], img.shape[0]), dtype=np.uint8), cv.COLOR_GRAY2BGR)
#参数cv2.RETR_EXTERNAL是获取最外层轮廓
hull = cv.convexHull(cnt)
cv.drawContours(black, [hull], -1, (0, 0, 255), 2)
#修正凸性缺陷的轮廓区域
cv.imshow("hull", black)
cv.waitKey(0)
cv.destroyAllWindows()
#program 11.点多边形测试
import numpy as np
import cv2 as cv 
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
dist = cv.pointPolygonTest(cnt,(50,50),True)
'''
第三个参数是measureDist。如果它是真的,它会找到有符号的距离
如果为假,则查找该点是在轮廓线内部还是外部(分别返回+1、-1和0)
如果不想找到距离,第三个参数为False,可使速度提高2-3倍
''''
#program 12.形状匹配
#cv.matchShapes(),比较两个形状或两个轮廓,并返回一个显示相似性的度量。结果越低,匹配越好。它是根据矩值计算出来的
import cv2 as cv
import numpy as np
img1 = cv.imread('G:\sundries\CVpictures\stars1.jpg',0)
img2 = cv.imread('G:\sundries\CVpictures\stars2.jpg',0)
ret, thresh = cv.threshold(img1, 127, 255,0)
ret, thresh2 = cv.threshold(img2, 127, 255,0)
contours,hierarchy = cv.findContours(thresh,2,1)
cnt1 = contours[0]
contours,hierarchy = cv.findContours(thresh2,2,1)
cnt2 = contours[0]
ret = cv.matchShapes(cnt1,cnt2,1,0.0)
print( ret )

你可能感兴趣的:(OpenCV,opencv,python,图像处理)