17_图像轮廓

# 图像轮廓


## 2.1 图像二值化

import cv2 #opencv的缩写为cv2
import matplotlib.pyplot as plt # matplotlib库用于绘图展示
import numpy as np   # numpy数值计算工具包



def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

img = cv2.imread('D:/pycharm/pycharm-cope/opencv/resource/photo/08_Car.png')
cv_show(img,'img')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 大于 17 的取 255,小于 127 的取 0
cv_show(thresh,'thresh')

## 2.2 轮廓检测

contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

# 做完二值后,再用图像轮廓检测函数再去做
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# cv_show(contours,'binary') # 返回的二值化后的图像
print(np.array(contours).shape) # 轮廓点的信息
print(hierarchy) # hierarchy 是把轮廓结果保存在层级结构当中,暂时用不上

## 2.3 绘制所有轮廓

# 传入参数:图像、轮廓、轮廓索引(自适应,画所有轮廓),颜色模式,线条厚度
# 注意需要copy,要不原图会变。。。
cv_show(img,'img')
draw_img = img.copy() # 若不用拷贝后的,而是用原图画轮廓,则画轮廓图绘把原始的输入图像重写,覆盖掉
res = cv2.drawContours(draw_img,contours,-1,(0,0,255),2)
cv_show(res,'res')

# 2.4 绘制某个轮廓

draw_img = img.copy()
res = cv2.drawContours(draw_img,contours,7,(0,0,255),2) # 画 7 号轮廓
cv_show(res,'res')

# 2.5 综合展示

img = cv2.imread('D:/pycharm/pycharm-cope/opencv/resource/photo/10_contours.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 大于17的取255,小于127的取0
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

draw_img = img.copy() # 若不用拷贝后的,而是用原图画轮廓,则画轮廓图绘把原始的输入图像重写,覆盖掉
res = cv2.drawContours(draw_img,contours,-1,(0,0,255),2) #-1表示画出所有图形的里面轮廓,可以换不同的数字进行测试
cv_show(res,'res')

# 3. 轮廓特征提取

img = cv2.imread('D:/pycharm/pycharm-cope/opencv/resource/photo/10_contours.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 大于17的取255,小于127的取0

contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

cnt = contours[0] # 通过轮廓索引,拿到该索引对应的轮廓特征
print(cv2.contourArea(cnt)) # 该轮廓的面积
print(cv2.arcLength(cnt,True)) # 该轮廓的周长,True表示闭合的

# 4. 轮廓近似

# 4.2 正常轮廓展示

img = cv2.imread('D:/pycharm/pycharm-cope/opencv/resource/photo/11_contours2.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 大于17的取255,小于127的取0

contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

draw_img = img.copy() # 若不用拷贝后的,而是用原图画轮廓,则画轮廓图绘把原始的输入图像重写,覆盖掉
res = cv2.drawContours(draw_img,contours,-1,(0,0,255),2) # -1表示里外轮廓都显示
cv_show(res,'res')

# 4.3 轮廓近似展示

img = cv2.imread('D:/pycharm/pycharm-cope/opencv/resource/photo/11_contours2.png')

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 大于17的取255,小于127的取0
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]

draw_img = img.copy()
res = cv2.drawContours(draw_img,[cnt],-1,(0,0,255),2)
cv_show(res,'res')

epsilon = 0.1 * cv2.arcLength(cnt,True) # 周长的百分比,这里用 0.1 的周长作阈值
approx = cv2.approxPolyDP(cnt,epsilon,True) # 第二个参数为阈值
draw_img = img.copy()
res = cv2.drawContours(draw_img,[approx],-1,(0,0,255),2)
cv_show(res,'res')

# 5. 外接矩形

img = cv2.imread('D:/pycharm/pycharm-cope/opencv/resource/photo/10_contours.png')

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 大于17的取255,小于127的取0
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[6]#里面的数字不同得到不同的信息,画出不一样的轮廓

x,y,w,h = cv2.boundingRect(cnt) # 可以得到矩形四个坐标点的相关信息
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255),2)
cv_show(img,'img')

area = cv2.contourArea(cnt)
rect_area = w * h
extent = float(area) / rect_area
print('轮廓面具与边界矩形比:',extent)

# 6. 外接圆

img = cv2.imread('D:/pycharm/pycharm-cope/opencv/resource/photo/10_contours.png')

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 大于17的取255,小于127的取0
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]

draw_img = img.copy()
(x,y),redius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
redius = int(redius)
img = cv2.circle(draw_img,center,redius,(0,255,0),2)
cv_show(img,'img')

 结果展示

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2022-08-03 11:51  tuyin  阅读(47)  评论(0)    收藏  举报