如何仅提取图像的圆形 ROI 部分并通过在 Python OpenCV GUI 的 Tkinter window 中单击按钮显示圆的半径
How to extract only circular ROI portion of the image and show Radius of the circle with a button click in Tkinter window of Python OpenCV GUI
提取圆形 ROI 并在 Tkinter 标签中显示圆的半径
我正在向该社区的 python 专家寻求帮助。我在整个 Stackexchange 以及 Github 社区中搜索了我的问题。但我没有找到任何有用的东西。
我创建了一个 Tkinter GUI。在此 GUI 中,我可以从目标文件夹上传我的图像。在评估部分Select,我写了一个脚本,通过它我可以自动查看我在圆形部分的ROI区域。 GUI 显示在该问题的底部。
需要帮助部分:我在创建脚本时遇到问题:
- 当我点击 上传 ROI 按钮时,只有选定的 ROI 部分
图像的一部分保存在目标文件夹中,即 path =
'Data/images/' + 名称 + '_' + 方法 + ext
- 我可以在 Tkinter 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()
, max()to get
0instead
-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
对于更多圈子,您必须首先计算用于所有圈子的区域(获取所有圈子的最小值 x-r
、y-r
和最大值 x+r
、y+r
) 和下一个裁剪图像。
稍后我会尝试使用alpha通道去除圆圈外的背景
用于测试的图像(如果其他人想测试代码)
编辑: 我添加了创建带有白色圆圈的黑色图像以删除背景的代码。
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
提取圆形 ROI 并在 Tkinter 标签中显示圆的半径
我正在向该社区的 python 专家寻求帮助。我在整个 Stackexchange 以及 Github 社区中搜索了我的问题。但我没有找到任何有用的东西。 我创建了一个 Tkinter GUI。在此 GUI 中,我可以从目标文件夹上传我的图像。在评估部分Select,我写了一个脚本,通过它我可以自动查看我在圆形部分的ROI区域。 GUI 显示在该问题的底部。
需要帮助部分:我在创建脚本时遇到问题:
- 当我点击 上传 ROI 按钮时,只有选定的 ROI 部分 图像的一部分保存在目标文件夹中,即 path = 'Data/images/' + 名称 + '_' + 方法 + ext
- 我可以在 Tkinter 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()
, max()to get
0instead
-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
对于更多圈子,您必须首先计算用于所有圈子的区域(获取所有圈子的最小值 x-r
、y-r
和最大值 x+r
、y+r
) 和下一个裁剪图像。
稍后我会尝试使用alpha通道去除圆圈外的背景
用于测试的图像(如果其他人想测试代码)
编辑: 我添加了创建带有白色圆圈的黑色图像以删除背景的代码。
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