图像分割可以理解为:提取图像的感兴趣区域,可以分为两部分:
第一步:获取mask区域:defgenerateMask(img):
def generateMask(img):
blured_img = getBlurImage(img) #①对图像进行高斯平滑滤波
filtered_img = getFilterImage(blured_img) #②对图像进行通用的2D滤波
opening_img = getOpeningImage(filtered_img) #③对图像进行开运算
closing_img = getClosingImage(opening_img) #④对图像进行闭运算
canny_edge_img = autoCannyEdgeDetection(closing_img) #⑤使用cv2.canny进行边缘检测
contours, contour_img = getContourImage(canny_edge_img) #⑥使用cv2.findContours寻找边缘轮廓
binary_line_img = drawLines(contour_img, contours) # ⑦绘制最小轮廓
dilation_img = getDilationImage(binary_line_img) #⑧对最小轮廓图像进行膨胀处理
return dilation_img
附函数:
①:对图像进行高斯平滑滤波
def getBlurImage(img):
blur = cv2.GaussianBlur(img, (5, 5), 0)
return blur
②:对图像进行通用的2D滤波
def getFilterImage(img):
kernel = np.ones((5, 5), np.float32) / 25
filtered = cv2.filter2D(img, -1, kernel)
return filtered
③:对图像进行开运算
def getOpeningImage(img):
kernel = np.ones((35,35),np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
return opening
④:对图像进行闭运算
def getClosingImage(img):
kernel = np.ones((35,35),np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
return closing
⑤:使用cv2.canny进行边缘检测
def autoCannyEdgeDetection(img, sigma = 0.7):
v = np.median(img)
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(img, 245, 255)
return edged
⑥:使用cv2.findContours寻找边缘轮廓
def getContourImage(img):
im2, contours, hierarchy = cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
mask = np.zeros(img.shape, np.uint8)
cv2.drawContours(mask, contours, -1, (255,255,255), 5)
return contours, mask
⑦:绘制最小轮廓
def drawLines(img, contours):
cnt = contours[0]
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
mask = np.zeros(img.shape, np.uint8)
cnt_points = []
for cnt in contours:
for pts in cnt:
cnt_points.append(pts[0])
cnt_points = np.array(cnt_points)
for i in range(len(cnt_points)):
cv2.line(mask,center,(cnt_points[i,0], cnt_points[i,1]),(255,255,255),5)
return mask
⑧:对最小轮廓图像进行膨胀处理
def getDilationImage(img):
kernel = np.ones((50,50),np.uint8)
dilation = cv2.dilate(img, kernel, iterations = 1)
return dilation
第二步:获取ROI区域:defextractRegion(img, mask):
其中,第二步的操作就是对img与mask进行的图像与运算。
def extractRegion(img, mask):
processed_img = cv2.bitwise_and(img, img, mask = mask)
return processed_img
补充:图像算数与逻辑运算
1、add---图像矩阵相加:def add(src1, src2, dst=None, mask=None, dtype=None) #图像的像素值增大
PS:src1:图像矩阵1,src2:图像矩阵2,dst:默认选项,mask:默认选项,dtype:默认选项。
2、subtract---图像矩阵相减:defsubtract(src1, src2, dst=None, mask=None, dtype=None)#图像的像素值减小
3、bitwise_and—图像与运算:defbitwise_and(src1, src2, dst=None, mask=None)#求两图像的交集
4、bitwise_or—图像或运算:defbitwise_or(src1, src2, dst=None, mask=None) #求两图像的并集
5、bitwise_xor—图像异或运算:defbitwise_xor(src1, src2, dst=None, mask=None) #求两图像的并集-交集
6、bitwise_not—图像非运算:defbitwise_not(src1, src2, dst=None, mask=None) #求图像的反(像素值的对调:意思就是原先的0换为1,原先的1换为0)