OpenCV轮廓排序
contours.sort(key=cnt_area, reverse=True) #排序
reverse:True表示降序 False表示降序
如果轮廓线是闭合的 就使用面积来排序使用
cv2.contourArea() 获得轮廓面积后进行排序:如下
import cv2
import numpy as np
from numpy import random as nr
from skimage import morphology,data,color
from skimage import img_as_float,img_as_ubyte
def imgContoursROI():
"""使用查找到的轮廓生成ROI剪切图片中感兴趣区域"""
img = cv2.imread('JP1.JPG') # 载入图像
cv2.imshow("src", img)
copyImg=img.copy() #原图像的拷贝
gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 160, 255, cv2.THRESH_BINARY) # 阈值化
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 寻找轮廓线
contours.sort(key=cnt_area, reverse=True) #排序
mask=np.zeros(img.shape, np.uint8) #原图大小的纯黑mask图像
draw=np.zeros(img.shape, np.uint8) #将原图 copyTo 到draw上,加上mask操作
temp=np.zeros(img.shape, np.uint8) #每次循环,重置mask 和 draw
i=0
for contour in contours: # 遍历所有轮廓
area = cv2.contourArea(contour) #轮廓图面积
B = 255
G = 255
R = 255 #生成颜色
mask=temp.copy()
draw=temp.copy()
if (area > 300) : #轮廓面积大于300的做 mask
x, y, w, h = cv2.boundingRect(contour)
cv2.drawContours(img,[contour],-1,(B,G,R),cv2.FILLED)
cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2, cv2.LINE_AA)
cv2.putText(img, "No.%d" % (i + 1), (x, y - 5), font, 0.8, (255, 0, 0), 2)
#ROIname='ROI{num}'.format(num=i)
#ROI = cv2.bitwise_and(img, mask) #图形与mask 的 and 运算
cv2.imshow("dstimg", img)
i+=1
cv2.waitKey(0)
def cnt_area(cnt):
"""返回轮廓的面积"""
area = cv2.contourArea(cnt)
return area
效果图
如果 轮廓不闭合,使用 长度来排序
cv2.arcLength(cnt,False)
代码如下:
def circle_fitness():
"""拟合图像中的圆,然后 去掉失真的图像"""
img = cv2.imread('JP1.JPG') # 载入图像
#cv2.imshow("src", img)
copyImg=img.copy() #原图像的拷贝
mask = np.zeros(img.shape, np.uint8) # 原图大小的纯黑mask图像
mask1 = np.zeros(img.shape, np.uint8) # 原图大小的纯黑mask图像
maskw = np.zeros(img.shape, np.uint8) # 原图大小的纯黑mask图像
maskw[:]=255 #生成白色mask图像
gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.namedWindow('src',cv2.WINDOW_AUTOSIZE)
himg = cv2.equalizeHist(gray) # 直方图均匀化
while (True):
ret, binary = cv2.threshold(himg, 132, 255, cv2.THRESH_BINARY) # 阈值化
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 寻找轮廓线
for contour in contours: # 遍历所有轮廓
area = cv2.contourArea(contour) # 轮廓图面积
B = nr.randint(1, 255)
G = nr.randint(1, 255)
R = nr.randint(1, 255)
if (area > 200): # 轮廓面积大于200的
#ellipse = cv2.fitEllipse(contour) #根据轮廓拟合椭圆
#cv2.ellipse(copyImg, ellipse, (B,G,R), 2, cv2.LINE_AA)
#x, y = ellipse[0]
circle=cv2.minEnclosingCircle(contour) #通过轮廓拟合最小外接圆
Cx,Cy=circle[0] #获得外接圆圆心点
r=circle[1] #获得外接圆半径
cv2.circle(mask, (np.int(Cx), np.int(Cy)) ,np.int(r-10) ,(255, 255, 255), -1, 8, 0)
ROI = cv2.bitwise_and(copyImg, mask) # 图形与mask 的 and 运算
#cv2.circle(copyImg, (np.int(x1), np.int(y1)), 4, (255, 0, 0), -1, 8, 0)
grayROI = cv2.cvtColor(ROI, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(grayROI, 100, 150, cv2.THRESH_BINARY) # 阈值化
#binary = cv2.adaptiveThreshold(grayROI, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 63, 8)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 寻找轮廓线
cv2.drawContours(mask1, contours, -1, (255, 255, 255), cv2.FILLED)
mask2=~mask1
dst = cv2.bitwise_and(mask2, mask) # 图形与mask 的 and 运算
cv2.imshow("dst", dst)
cv2.imshow("src", img)
break
return dst
def get_SkeletonSkimage(img):
mask1 = np.zeros(img.shape, np.uint8) # 原图大小的纯黑mask图像
skim=opencv2skimage(img) #转换图像格式opencv图像格式转skimage图像格式
image = color.rgb2gray(skim) #skimage转灰度图
skeleton = morphology.skeletonize(image)
dstimg=skimage2opencv(skeleton) #转换图像格式skimage图像格式专opencv格式
#gray=cv2.cvtColor(dstimg,cv2.COLOR_BGR2GRAY) #opencv 转灰度图
contours, hierarchy = cv2.findContours(dstimg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 寻找轮廓线
contours.sort(key=cnt_length, reverse=True)
#cv2.drawContours(mask1, contours, -1, (255, 255, 255), cv2.FILLED)
#arrimgContours=np.array(contours)
i=0
for contour in contours: # 遍历所有轮廓
#arrimg=np.array(contour)
#size=arrimg.size
x, y, w, h = cv2.boundingRect(contour)
#area = cv2.contourArea(contour) # 轮廓图面积
B = nr.randint(1, 255)
G = nr.randint(1, 255)
R = nr.randint(1, 255)
cv2.rectangle(mask1, (x, y), (x + w, y + h), (255, 0, 0), 2, cv2.LINE_AA)
cv2.putText(mask1, "No.%d" % (i + 1), (x, y - 5), font, 0.8, (255, 0, 0), 2)
cv2.drawContours(mask1, [contour], -1, (B, G, R), cv2.FILLED)
i += 1
cv2.imshow('SkeletonContours', mask1)
cv2.waitKey()
def cnt_length(cnt):
"""length"""
length = cv2.arcLength(cnt,False)
return length
if __name__ == "__main__":
#myFindContours()
#imgContoursROI()
#getContoursInROI()
#TrackbarThreshold()
#get_SkeletonSkimage(circle_fitness())
效果图: