要求
- 利用QLabel控件显示图片;
- 鼠标点击,获取单机坐标,根据四个顶点坐标,在图中画出截取区域;
- 确定,根据鼠标点击的四个点,求取单适应矩阵,做图像较正。
说明
画图
在QLabel画图,需要继承QLabel类,重写paintEvent和mouseReleaseEvent。
需要注意的是,在mouseReleaseEvent中获取鼠标点击的点的时候,global_point = event.globalPos()是在你1920*1080的屏幕上的点击坐标,event.pos()是你在UI窗口中的坐标,UI界面左上角为(0,0),而用event.globalPos()获取UI界面左上角的坐标可能是(765,532),一般不为0。而真实对应的图片中的坐标则是pos()-(centralWidget.pos()+leftImgLabel.pos())具体见参考3。
有一个简单的方法,获得真实图片中的坐标,利用self.mapFromGlobal(global_point)即可。
在ImageLabel类中,pantEvent和mouseReleaseEvent代码如下:
def paintEvent(self, event):
QLabel.paintEvent(self, event)
painter = QPainter()
painter.begin(self)
pen = QPen(Qt.red, 4 , Qt.DashDotLine)#虚线画笔
painter.setPen(pen)
for k in range(len(self.points)):
if k + 1 != len(self.points):
painter.drawLine(self.points[k][0], self.points[k][1], self.points[k + 1][0], self.points[k + 1][1])
else:
painter.drawLine(self.points[k][0], self.points[k][1], self.points[0][0], self.points[0][1])
painter.end()
# 开启标记功能时,获取点击坐标
def mouseReleaseEvent(self, event):
if len(self.points) < 4:
global_point = event.globalPos()
local_point = self.mapFromGlobal(global_point)
point_x = local_point.x()
point_y = local_point.y()
self.points.append([point_x, point_y])
self.update()#获取鼠标点击的点之后,通知画线
功能如下:
求解单适应矩阵
可以用 h, s = cv2.findHomography(src_point, dst_point, cv2.RANSAC, 10) 来求解。
我们获取上面的点范围是(400, 600)之后,需要利用mapfromLoal()函数,将点击的坐标,还原到真实图像(3024, 4536)上,需要注意的是,要让上面两个坐标值,是按比例缩放,否则,会有问题。mapfromLoal()代码如下:
def mapfromLoal(self, points):
points_origanal = []
y_ratio = np.float32(self.image.shape[0] / self.image_label.height())
x_ratio = np.float32(self.image.shape[1] / self.image_label.width())
for point in points:
points_origanal.append([point[0] * x_ratio, point[1] * y_ratio])
return points_origanal
单适应矩阵求解如下:
points = self.image_label.get_points()#获取image_label上点击的点
#单适应矩阵
po