求助:cv2.rectangle根据点击坐标绘制正方形形状异常
问题:cv2.rectangle绘制正方形形状异常,点击坐标计算正常
问题描述
通过Matplotlib点击事件获取图像上的点P(x,y),以此为中心绘制边长64的正方形,但cv2.rectangle绘制出形状异常的矩形。坐标计算结果正常,且用相同坐标裁剪图像能得到预期正方形区域,但绘制问题未解决。GUI基于QtDesigner搭建。
相关代码
点击事件与绘制代码
frameSize = 64 ix, iy = 0, 0 def onclick(event): global ix, iy # 获取用户点击坐标 ix, iy = event.xdata, event.ydata print (f'Center:\tx = {ix}, y = {iy} frameSize = {frameSize}') # 计算矩形顶点坐标 print ("----------------------") left_TOP_x = int(ix - frameSize/2) left_TOP_y = int(iy - frameSize/2) right_BOTTOM_x = int(ix + frameSize/2) right_BOTTOM_y = int(iy + frameSize/2) print (f'to int\t left_TOP_x = {left_TOP_x}, left_TOP_y = {left_TOP_y}') print (f'to int\t right_BOTTOM_x = {right_BOTTOM_x}, right_BOTTOM_y = {right_BOTTOM_y}') print ("----------------------\n") # 绘制正方形(原错误代码) cv2.rectangle(img, (left_TOP_x,left_TOP_y,right_BOTTOM_x, right_BOTTOM_y ), color=(255, 0, 0), thickness= 2) window.ax.imshow(img) window.canvas.draw()
坐标输出结果(首次点击,图像尺寸254x199)
Center: x = 131.67556141774892, y = 111.16829004329006 frameSize = 64 ---------------------- to int left_TOP_x = 99, left_TOP_y = 79 to int right_BOTTOM_x = 163, right_BOTTOM_y = 143 ----------------------
QtDesigner相关GUI代码
self.plotWidget = QtWidgets.QWidget(self.verticalLayoutWidget) self.verticalLayout.addWidget(self.plotWidget) self.plotWidget.setStyleSheet("") self.plotWidget.setObjectName("plotWidget") self.plotLayout = QtWidgets.QVBoxLayout(self.plotWidget) self.plotLayout.setContentsMargins(0, 0, 0, 0) self.plotLayout.setObjectName("plotLayout")
问题根源与解决方案
问题出在cv2.rectangle的参数传递错误:OpenCV的rectangle函数要求第二个参数是两个独立的元组——第一个是左上角坐标(x1, y1),第二个是右下角坐标(x2, y2),而非将四个坐标塞进同一个元组。
修正后的绘制代码
# 拆分坐标为两个元组传递 cv2.rectangle(img, (left_TOP_x, left_TOP_y), (right_BOTTOM_x, right_BOTTOM_y), color=(255, 0, 0), thickness=2) window.ax.imshow(img) window.canvas.draw()
额外优化建议
如果需要保留原始图像、避免多次点击后叠加绘制,建议复制图像副本进行操作:
img_copy = img.copy() cv2.rectangle(img_copy, (left_TOP_x, left_TOP_y), (right_BOTTOM_x, right_BOTTOM_y), color=(255, 0, 0), thickness=2) window.ax.imshow(img_copy) window.canvas.draw()
内容的提问来源于stack exchange,提问作者Dodeo
相关产品推荐
相关产品推荐

