Qt图像蒙版区域复制异常:仅左上角起始选择有效
蒙版区域复制异常问题:仅左上角起始绘制正常,其他角落出错
我实现了为图像添加蒙版并将蒙版内区域复制至另一图像的功能,但仅当从图像左上角开始绘制蒙版时功能正常,从其他角落起始绘制时,复制的区域会出现错误。我尝试通过判断蒙版选择的顺时针/逆时针方向来修正该问题,但并未奏效。
原实现代码
def add_mask(self): self.analysis_image_duplicate.mousePressEvent = self.start_mask self.analysis_image_duplicate.mouseMoveEvent = self.update_mask self.analysis_image_duplicate.mouseReleaseEvent = self.end_mask # Enable the select_roi_button once the add_mask_button has been clicked self.select_roi_button.setEnabled(True) # Function to handle the start of the mask drawing process def start_mask(self, event): rel_position = calc_relative_position(event.pos(), self.analysis_image.pixmap()) self.mask_rect = QtCore.QRect(rel_position, rel_position) self.apply_mask() # Function to update the mask during the drawing process def update_mask(self, event): rel_position = calc_relative_position(event.pos(), self.analysis_image.pixmap()) self.mask_rect.setBottomRight(QtCore.QPoint(rel_position.x(), rel_position.y())) self.apply_mask() # Function to handle the end of the mask drawing process def end_mask(self, event): self.update_mask(event) self.analysis_image_duplicate.mousePressEvent = self.start_mask self.analysis_image_duplicate.mouseMoveEvent = self.update_mask self.analysis_image_duplicate.mouseReleaseEvent = self.end_mask max_allowed_width = int(250 / self.scale_factor) if self.mask_rect.width() > max_allowed_width: self.mask_rect.setWidth(max_allowed_width) QMessageBox.warning(self, 'Warning', f'Mask area Width cannot exceed 250. Width reduced to 250.', QMessageBox.Ok) max_allowed_height = int(1200 / self.scale_factor) if self.mask_rect.height() > max_allowed_height: self.mask_rect.setHeight(max_allowed_height) QMessageBox.warning(self, 'Warning', f'Mask area Height cannot exceed 1200. Height reduced to 1200.', QMessageBox.Ok) self.roi_rect = QtCore.QRect( self.mask_rect.left(), self.mask_rect.top(), 1, self.mask_rect.height() ) self.roi_button = QPushButton(self.analysis_image_duplicate) self.roi_button.setGeometry( self.mask_rect.right() - 5, self.mask_rect.top(), 5, self.mask_rect.height() ) self.roi_button.setCursor(QtCore.Qt.SizeHorCursor) self.roi_button.installEventFilter(self) self.apply_mask() # Function to apply the mask to the analysis image def apply_mask(self): if self.analysis_image.pixmap(): mask_pixmap = self.analysis_image.pixmap().copy() painter = QPainter(mask_pixmap) painter.setPen(QPen(Qt.red, 1)) painter.drawRect(self.mask_rect) if self.roi_rect: painter.setPen(QPen(Qt.green, 1)) painter.drawRect(self.roi_rect) painter.end() display_image(self.analysis_image_duplicate, mask_pixmap) self.apply_mask_to_template() # Function to apply the mask to the template image and copy the ROI def apply_mask_to_template(self): if self.template_image.pixmap(): self.mask_pixmap = self.template_image.pixmap().copy() painter = QPainter(self.mask_pixmap) if self.analysis_image.pixmap(): analysis_pixmap = self.analysis_image.pixmap().copy(self.mask_rect) # Shift analysis_pixmap to paste_point's coordinates, adjusting for height self.target_rect = QtCore.QRect(self.paste_point.x(), self.paste_point.y() - self.mask_rect.height(), self.mask_rect.width(), self.mask_rect.height()) painter.drawPixmap(self.target_rect, analysis_pixmap) # Set the pen for drawing the blue lines painter.setPen(QPen(Qt.blue, 1, Qt.DashLine)) # Draw blue lines that cross top_line_start = QtCore.QPoint(0, self.target_rect.top()) top_line_end = QtCore.QPoint(self.mask_pixmap.width(), self.target_rect.top()) bottom_line_start = QtCore.QPoint(0, self.target_rect.bottom()) bottom_line_end = QtCore.QPoint(self.mask_pixmap.width(), self.target_rect.bottom()) left_line_start = QtCore.QPoint(self.target_rect.left(), 0) left_line_end = QtCore.QPoint(self.target_rect.left(), self.mask_pixmap.height()) right_line_start = QtCore.QPoint(self.target_rect.right(), 0) right_line_end = QtCore.QPoint(self.target_rect.right(), self.mask_pixmap.height()) painter.drawLine(top_line_start, top_line_end) painter.drawLine(bottom_line_start, bottom_line_end) painter.drawLine(left_line_start, left_line_end) painter.drawLine(right_line_start, right_line_end) if self.roi_rect and self.paste_point: painter.setPen(QPen(Qt.green, 1)) roi_top_left = QtCore.QPoint(max(self.roi_rect.left() - self.mask_rect.left(), 0), max(self.roi_rect.top() - self.mask_rect.top(), 0)) roi_bottom_right = QtCore.QPoint( min(self.roi_rect.right() - self.mask_rect.left(), self.target_rect.width()), min(self.roi_rect.bottom() - self.mask_rect.top(), self.target_rect.height())) limited_roi_rect = QtCore.QRect(self.target_rect.topLeft() + roi_top_left, self.target_rect.topLeft() + roi_bottom_right) painter.drawRect(limited_roi_rect) # Create left and right part of the mask pixmap self.left_part = self.mask_pixmap.copy(0, 0, self.target_rect.left(), self.mask_pixmap.height()) self.right_part = self.mask_pixmap.copy(self.target_rect.right(), 0, self.mask_pixmap.width() - self.target_rect.right(), self.mask_pixmap.height()) painter.end() display_image(self.template_image_duplicate, self.mask_pixmap) self.copy_roi_to_template()
尝试修复的代码(未解决问题)
def add_mask(self): self.analysis_image_duplicate.mousePressEvent = self.start_mask self.analysis_image_duplicate.mouseMoveEvent = self.update_mask self.analysis_image_duplicate.mouseReleaseEvent = self.end_mask # Enable the select_roi_button once the add_mask_button has been clicked self.select_roi_button.setEnabled(True) # Function to handle the start of the mask drawing process def start_mask(self, event): rel_position = calc_relative_position(event.pos(), self.analysis_image.pixmap()) self.mask_rect = QtCore.QRect(rel_position, rel_position) self.apply_mask() # Function to update the mask during the drawing process def update_mask(self, event): rel_position = calc_relative_position(event.pos(), self.analysis_image.pixmap()) self.mask_rect.setBottomRight(QtCore.QPoint(rel_position.x(), rel_position.y())) self.apply_mask() # Function to handle the end of the mask drawing process def end_mask(self, event): self.update_mask(event) self.analysis_image_duplicate.mousePressEvent = self.start_mask self.analysis_image_duplicate.mouseMoveEvent = self.update_mask self.analysis_image_duplicate.mouseReleaseEvent = self.end_mask max_allowed_width = int(250 / self.scale_factor) if self.mask_rect.width() > max_allowed_width: self.mask_rect.setWidth(max_allowed_width) QMessageBox.warning(self, 'Warning', f'Mask area Width cannot exceed 250. Width reduced to 250.', QMessageBox.Ok) max_allowed_height = int(1200 / self.scale_factor) if self.mask_rect.height() > max_allowed_height: self.mask_rect.setHeight(max_allowed_height) QMessageBox.warning(self, 'Warning', f'Mask area Height cannot exceed 1200. Height reduced to 1200.', QMessageBox.Ok) self.roi_rect = QtCore.QRect( self.mask_rect.left(), self.mask_rect.top(), 1, self.mask_rect.height() ) self.roi_button = QPushButton(self.analysis_image_duplicate) self.roi_button.setGeometry( self.mask_rect.right() - 5, self.mask_rect.top(), 5, self.mask_rect.height() ) self.roi_button.setCursor(QtCore.Qt.SizeHorCursor) self.roi_button.installEventFilter(self) self.apply_mask() # Function to apply the mask to the analysis image def apply_mask(self): if self.analysis_image.pixmap(): mask_pixmap = self.analysis_image.pixmap().copy() painter = QPainter(mask_pixmap) painter.setPen(QPen(Qt.red, 1)) painter.drawRect(self.mask_rect) if self.roi_rect: painter.setPen(QPen(Qt.green, 1)) painter.drawRect(self.roi_rect) painter.end() display_image(self.analysis_image_duplicate, mask_pixmap) self.apply_mask_to_template() # Function to apply the mask to the template image and copy the ROI def apply_mask_to_template(self): if self.template_image.pixmap(): self.mask_pixmap = self.template_image.pixmap().copy() painter = QPainter(self.mask_pixmap) if self.analysis_image.pixmap(): analysis_pixmap = self.analysis_image.pixmap().copy(self.mask_rect) # Shift analysis_pixmap to paste_point's coordinates, adjusting for height self.target_rect = QtCore.QRect(self.paste_point.x(), self.paste_point.y() - self.mask_rect.height(), self.mask_rect.width(), self.mask_rect.height()) painter.drawPixmap(self.target_rect, analysis_pixmap) # Set the pen for drawing the blue lines painter.setPen(QPen(Qt.blue, 1, Qt.DashLine)) # Draw blue lines that cross top_line_start = QtCore.QPoint(0, self.target_rect.top()) top_line_end = QtCore.QPoint(self.mask_pixmap.width(), self.target_rect.top()) bottom_line_start = QtCore.QPoint(0, self.target_rect.bottom()) bottom_line_end = QtCore.QPoint(self.mask_pixmap.width(), self.target_rect.bottom()) left_line_start = QtCore.QPoint(self.target_rect.left(), 0) left_line_end = QtCore.QPoint(self.target_rect.left(), self.mask_pixmap.height()) right_line_start = QtCore.QPoint(self.target_rect.right(), 0) right_line_end = QtCore.QPoint(self.target_rect.right(), self.mask_pixmap.height()) painter.drawLine(top_line_start, top_line_end) painter.drawLine(bottom_line_start, bottom_line_end) painter.drawLine(left_line_start, left_line_end) painter.drawLine(right_line_start, right_line_end) if self.roi_rect and self.paste_point: painter.setPen(QPen(Qt.green, 1)) roi_top_left = QtCore.QPoint(max(self.roi_rect.left() - self.mask_rect.left(), 0), max(self.roi_rect.top() - self.mask_rect.top(), 0)) roi_bottom_right = QtCore.QPoint( min(self.roi_rect.right() - self.mask_rect.left(), self.target_rect.width()), min(self.roi_rect.bottom() - self.mask_rect.top(), self.target_rect.height())) limited_roi_rect = QtCore.QRect(self.target_rect.topLeft() + roi_top_left, self.target_rect.topLeft() + roi_bottom_right) painter.drawRect(limited_roi_rect) # Create left and right part of the mask pixmap self.left_part = self.mask_pixmap.copy(0, 0, self.target_rect.left(), self.mask_pixmap.height()) self.right_part = self.mask_pixmap.copy(self.target_rect.right(), 0, self.mask_pixmap.width() - self.target_rect.right(), self.mask_pixmap.height()) painter.end() display_image(self.template_image_duplicate, self.mask_pixmap) self.copy_roi_to_template()
内容的提问来源于stack exchange,提问作者Kei Emile Daisy
相关产品推荐
相关产品推荐

