提取圆形 ROI 并在 Tkinter 标签中显示圆形的半径
我正在向这个社区的 python 专家请求帮助。我已经在 Stackexchange 以及 Github 社区中搜索了我的问题。但我没有发现任何有用的东西。
我创建了一个 Tkinter GUI。在这个 GUI 中,我可以从目标文件夹上传我的图像。在评估部分的选择中,我编写了一个脚本,通过它可以自动查看圆形部分的 ROI 区域。 GUI 显示在此问题的底部。
需要帮助部分 :我在创建脚本时遇到了麻烦,通过该脚本:
图像保存在目标文件夹,即 路径 =
'数据/图像/' + 名称 + '_' + 方法 + 分机
def ROI(self, image, method):
if method == 'ROI':
image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
blimage = cv2.medianBlur(image, 15)
circles = cv2.HoughCircles(blimage, cv2.HOUGH_GRADIENT, 1, 255, param1=100, param2=60, minRadius=0,
maxRadius=0)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0, :]:
cv2.circle(image, (i[0], i[1]), i[2], (0, 255, 0), 6)
cv2.circle(image, (i[0], i[1]), 2, (0, 0, 255), 3)
cv2.waitKey()
else:
print('method is wrong')
return image
界面
最佳答案
更新:
我添加了变量 border
计算 x1,y1,x2,y2
所以现在它带有边界线。图像显示不带 border
的旧代码的结果.
如果你只有一个圈子(x,y,r)
然后你可以用它来裁剪图像
image = image[y-r:y+r, x-r:x+r]
我在一些图像上测试它,圆圈比图像大,我不得不使用
int16
而不是 unit16
获取 -1
而不是 65535
对于 170-171
(y-r
)。添加我必须使用 min()
, 最大值() to get
0 instead
-1`def ROI(self, image, method):
if method == 'ROI':
image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
blimage = cv2.medianBlur(image, 15)
circles = cv2.HoughCircles(blimage, cv2.HOUGH_GRADIENT, 1, 255, param1=100, param2=60, minRadius=0,
maxRadius=0)
if circles is not None:
#print(circles)
# need `int` instead of `uint` to correctly calculate `y-r` (to get `-1` instead of `65535`)
circles = np.int16(np.around(circles))
for x,y,r in circles[0, :]:
print('x, y, r:', x, y, r)
border = 6
cv2.circle(image, (x, y), r, (0, 255, 0), border)
cv2.circle(image, (x, y), 2, (0, 0, 255), 3)
height, width = image.shape
print('height, width:', height, width)
# calculate region to crop
x1 = max(x-r - border//2, 0) # eventually -(border//2+1)
x2 = min(x+r + border//2, width) # eventually +(border//2+1)
y1 = max(y-r - border//2, 0) # eventually -(border//2+1)
y2 = min(y+r + border//2, height) # eventually +(border//2+1)
print('x1, x2:', x1, x2)
print('y1, y2:', y1, y2)
# crop image
image = image[y1:y2,x1:x2]
print('height, width:', image.shape)
else:
print('method is wrong')
return image
对于更多圆圈,您必须首先计算用于所有圆圈的区域(获取 drom 所有圆圈最小值
x-r
, y-r
和最大值 x+r
, y+r
)和下一个裁剪图像。稍后我会尝试使用 alpha channel 来去除圆圈外的背景。
用于测试的图像(如果其他人想测试代码)
编辑:我添加了创建带有白色圆圈的黑色图像以删除背景的代码。
def ROI(self, image, method):
if method == 'ROI':
image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
blimage = cv2.medianBlur(image, 15)
circles = cv2.HoughCircles(blimage, cv2.HOUGH_GRADIENT, 1, 255, param1=100, param2=60, minRadius=0,
maxRadius=0)
if circles is not None:
print(circles)
circles = np.int16(np.around(circles)) # need int instead of uint to correctly calculate y-r (to get -1 instead of 65535)
for x,y,r in circles[0, :]:
print('x, y, r:', x, y, r)
height, width = image.shape
print('height, width:', height, width)
border = 6
cv2.circle(image, (x, y), r, (0, 255, 0), border)
cv2.circle(image, (x, y), 2, (0, 0, 255), 3)
mask = np.zeros(image.shape, np.uint8) # black background
cv2.circle(mask, (x, y), r, (255), border) # white mask for black border
cv2.circle(mask, (x, y), r, (255), -1) # white mask for (filled) circle
#image = cv2.bitwise_and(image, mask) # image with black background
image = cv2.bitwise_or(image, ~mask) # image with white background
x1 = max(x-r - border//2, 0) # eventually -(border//2+1)
x2 = min(x+r + border//2, width) # eventually +(border//2+1)
y1 = max(y-r - border//2, 0) # eventually -(border//2+1)
y2 = min(y+r + border//2, height) # eventually +(border//2+1)
print('x1, x2:', x1, x2)
print('y1, y2:', y1, y2)
image = image[y1:y2,x1:x2]
print('height, width:', image.shape)
else:
print('method is wrong')
return image
关于python - 如何仅提取图像的圆形 ROI 部分并通过在 Python OpenCV GUI 的 Tkinter 窗口中单击按钮来显示圆的半径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59477313/