'''
此方法是一种动态自适应找圆方法
使用方法:
im_floodfill = get_adaptive_circle(crop_img)
输入原图crop_img
返回mask
'''
import os
import cv2
import numpy as np
# 求最大连通域的中心点坐标
# def centroid(max_contour):
# moment = cv2.moments(max_contour)
# if moment['m00'] != 0:
# cx = int(moment['m10'] / moment['m00'])
# cy = int(moment['m01'] / moment['m00'])
# return cx, cy
# else:
# return None
def fillHole(im_in):
im_floodfill = im_in.copy()
im_floodfill = np.uint8(im_floodfill)
row, col, dim = im_floodfill.shape
# Mask used to flood filling
# Notice the size needs to be 2 pixels than the image
mask = np.zeros((row+2, col+2), np.uint8)
# Floodfill from point int(row/2), int(col/2)
cv2.floodFill(im_floodfill, mask, (int(row/2), int(col/2)), (255, 255,255))
# cv2.morphologyEx(im_floodfill, cv2.MORPH_ELLIPSE, mask)
return im_floodfill
def get_adaptive_circle(crop_img):
ori_row, ori_col, ori_dim = crop_img.shape
img = cv2.resize(crop_img, (240, 270))
row, col, dim = img.shape
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图像
edges = cv2.Canny(gray, 100, 200)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15)) # 圆形kernel
closing = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel, 100)
# 提取边缘
contours, hierarchy = cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 找到最大的contour
area = []
for j in range(len(contours)):
area.append(cv2.contourArea(contours[j]))
max_idx = np.argmax(area)
# 求椭圆
ellipse = cv2.fitEllipse(contours[max_idx])
ellipse_img = np.zeros((row, col, dim))
cv2.ellipse(ellipse_img, ellipse, (255, 255, 255), 2)
# 填充椭圆
ellipse_fill = fillHole(ellipse_img)
ellipse_fill = cv2.resize(ellipse_fill, (ori_row, ori_col))
ret, ellipse_fill = cv2.threshold(ellipse_fill[:, :, 0], 0, 255, cv2.THRESH_BINARY | cv2.THRESH_TRIANGLE)
# cv2.imshow('Canny', edges)
# cv2.imshow('closing', closing)
# cv2.imshow('ellipse_img', ellipse_img)
# cv2.imshow('ellipse_fill', ellipse_fill)
#
# cv2.waitKey(0)
return ellipse_fill
if __name__ == '__main__':
img = cv2.imread("/home/1.png")
crop_img = img[650:1400, 1000:1750]
ellipse = get_adaptive_circle(crop_img)
# save_img_path = os.path.join(save_path, imgs_list[i])
# cv2.imwrite(save_img_path, ellipse)
cv2.Canny(img, threshold1, threshold2)
https://www.cnblogs.com/aoru45/p/9763988.html
其中,较大的阈值2用于检测图像中明显的边缘,但一般情况下检测的效果不会那么完美,边缘检测出来是断断续续的。所以这时候用较小的第一个阈值用于将这些间断的边缘连接起来。
函数返回的是二值图,包含检测出的边缘
'''
此方法是一种简单的在固定位置上画圆的方法, 动态自适应画圆请参考:get_adaptive_circle.py
使用方法:
im_floodfill = get_circle(crop_img)
输入原图crop_img
返回mask
默认圆心坐标:
center_row, center_col = int(row // 2), int(col // 2)
默认半径:
radius = int(row // 2 - 10)
'''
import cv2
import numpy as np
def fillHole(im_in):
im_floodfill = im_in.copy()
im_floodfill = np.uint8(im_floodfill)
row, col, dim = im_floodfill.shape
# Mask used to flood filling
# Notice the size needs to be 2 pixels than the image
mask = np.zeros((row+2, col+2), np.uint8)
# Floodfill from point int(row/2), int(col/2)
cv2.floodFill(im_floodfill, mask, (int(row/2), int(col/2)), (255, 255,255))
# cv2.morphologyEx(im_floodfill, cv2.MORPH_ELLIPSE, mask)
return im_floodfill
def get_circle(crop_img):
row, col, dim = crop_img.shape
center_row, center_col = int(row // 2), int(col // 2)
radius = int(row // 2 - 10)
ellipse = np.zeros((row, col, dim))
cv2.circle(ellipse, (center_row, center_col), radius, (255, 255, 255), 2)
im_floodfill = fillHole(ellipse)
cv2.imshow("ellipse", ellipse)
cv2.imshow("crop_img", crop_img)
cv2.imshow("im_floodfill", im_floodfill)
cv2.waitKey(0)
return im_floodfill
if __name__ == '__main__':
img = cv2.imread("/home/pi/1.png")
crop_img = img[650:1400, 1000:1750]
im_floodfill = get_circle(crop_img)
# save_img_path = os.path.join(save_path, imgs_list[i])
# cv2.imwrite(save_img_path, im_floodfill)