opencv 用python在png中找到被点击的矩形

ntjbwcob  于 2023-08-06  发布在  Python
关注(0)|答案(3)|浏览(134)

我有一个包含矩形的PNG。我想显示这个png,这样用户就可以在其中一个矩形内单击,返回的值是矩形的左上角和右下角的像素坐标。
这是一张有代表性的图片。

的数据
我试着找出如何在opencv中使用blob检测和将鼠标点击坐标Map到其中一个blob来实现这一点,但我一直在安装和工作opencv时碰壁。在这种情况下,opencv是正确的库吗?
下面的代码只找到大约8个blob

# Standard imports
import cv2
import numpy as np

# Read image
im = cv2.imread("/home/mainmeister/PycharmProjects/WarehousrLineMap/public/warehouse.png", cv2.IMREAD_GRAYSCALE)

# Set up the detector with default parameters.
parameters = cv2.SimpleBlobDetector_Params()
parameters.filterByColor = 1
parameters.blobColor = 255
#detector = cv2.SimpleBlobDetector()
detector = cv2.SimpleBlobDetector_create(parameters)

# Detect blobs.
keypoints = detector.detect(im)

# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob
#im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]),(255,0,0),cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

# Show keypoints
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)

字符串

5kgi1eie

5kgi1eie1#

应用“连接组件标签”(带统计信息)。这可能需要一些预处理(阈值处理)。标签为您提供了一个“图像”,其中包含每个像素的“标签”(数字)。
然后,如果你点击任何像素,你可以立即查找其边界框。


的数据
视频:https://imgur.com/a/vSnnjSE(绿色框被放大以便于可视化)
一些核心逻辑:

floorplan = cv.imread("14rgT.png")
(height, width) = floorplan.shape[:2]

lower = (192,) * 3
upper = (255,) * 3
mask = cv.inRange(floorplan, lower, upper)

(nlabels, labels, stats, centroids) = cv.connectedComponentsWithStats(mask)

# the_label = labels[y,x] # mouse click coordinates
# (x0,y0,w,h,area) = stats[the_label] # bounding box, true area in pixels

字符串
剩下的就是GUI了。
这对于具有适当的连续周界的“房间”是敏感的。墙上的任何洞都将连接房间。
你可以通过形态学操作在一定程度上解决这个问题。

6pp0gazn

6pp0gazn2#

您可以使用捕获鼠标点击的回调函数来显示图像,而不是检测blob。当你点击图像时,你可以记录你点击的矩形的左上角和右下角的坐标。
以下是您的操作方法:

import cv2

def mouse_callback(event, x, y, flags, param):
    global tl_x, tl_y, br_x, br_y, drawing
if event == cv2.EVENT_LBUTTONDOWN:
    drawing = True
    tl_x, tl_y = x, y
elif event == cv2.EVENT_LBUTTONUP:
    drawing = False
    br_x, br_y = x, y
    cv2.rectangle(img, (tl_x, tl_y), (br_x, br_y), (0, 255, 0), 2)
    cv2.imshow("Image", img)
    print(f"Top-left coordinates: ({tl_x}, {tl_y}), Bottom-right coordinates: ({br_x}, {br_y})")

# Read image
img = cv2.imread("G:\ITI\yy.png")

# Create a window to display the image
cv2.namedWindow("Image")

# Initialize variables
tl_x, tl_y, br_x, br_y = -1, -1, -1, -1
drawing = False

# Set the mouse callback function
cv2.setMouseCallback("Image", mouse_callback)

# Display the image
cv2.imshow("Image", img)

# Wait until a key is pressed
cv2.waitKey(0)

# Destroy all OpenCV windows
cv2.destroyAllWindows()

字符串
输出样本

Top-left coordinates: (489, 388), Bottom-right coordinates: (489, 388)
Top-left coordinates: (284, 329), Bottom-right coordinates: (284, 329)
Top-left coordinates: (200, 151), Bottom-right coordinates: (200, 151)


这是输出

的图像

yws3nbqq

yws3nbqq3#

我建议首先使用Harris Corner DetectionOpenCV example)获取图像中的角点。
x1c 0d1x的数据
正如您所看到的,角点被正确检测到。如果没有,我建议使用OpenCV中记录的参数。
注意:以上只是为了演示,您可能还需要一些预处理,例如侵 eclipse 和/或噪声去除(如果需要),但这是经验性的,我将其留给您。
现在只需获得鼠标点击的坐标(检查Fatema的答案如何获得tl_x和tl_y),并检查您从Harris角检测步骤获得的角中的哪一个最接近。如果你想要左上角,那么只检查点击点的左上角。
如果有可能出现虚假点击(错误),则在x-y方向上从点击点开始的距离上添加一个阈值,直到您将检查角。

替代方法我没有使用过这个方法,但是你可以尝试使用 scikit-image 实现Harris角点检测,然后使用 corner_peaks 从图像中提取峰值,如图here所示。这个看起来更方便。

相关问题