【发布时间】:2021-10-26 07:29:27
【问题描述】:
我在 Pyqt 中创建了一个简单的 GUI,通过按钮上传包含图像路径和边界框坐标值的 CSV 文件。它还有另一个按钮,可以转到下一个图像。以及显示图像的标签区域,其中包含对象周围的边界框,如下所示。
现在我想为带有边界框的对象指定一些名称。为此,我有另一个按钮。但是,当图像中有多个对象时,我想单击其中一个边界框,然后分配相同的对象。但我正在努力使这个边界框区域可点击。
我已经看到了单击图像时获取像素值或 (x, y) 的示例,但这对我来说似乎很难。
下面是相同的代码。
同样的代码如下。
from PyQt5 import QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtWidgets import QApplication
import csv
from pygui import Ui_MainWindow
from collections import namedtuple
import sys
import cv2
Row = namedtuple('Row', ('image_path', 'x', 'y', 'w', 'h'))
class mainProgram(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(mainProgram, self).__init__(parent)
self.setupUi(self)
self.data=None
def all_callbacks(self):
# Open directory callback
self.Upload.clicked.connect(self.on_click_upload)
# Next button callback
self.Next.clicked.connect(self.on_click_next)
def convert_cv_image_to_qt(self, cv_img):
rgb_image = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
h, w, ch = rgb_image.shape
bytes_per_line = ch * w
convert_to_Qt_format = QtGui.QImage(rgb_image.data, w, h, bytes_per_line, QtGui.QImage.Format_RGB888)
return QtGui.QPixmap.fromImage(convert_to_Qt_format)
def draw_bb_on_image(self, image_data, color=(0, 0, 255), thickness=2):
self.image_path = image_data.image_path
self.x, self.y = int(image_data.x), int(image_data.y)
self.w, self.h = int(image_data.w), int(image_data.h)
image = cv2.imread(self.image_path)
output_img = cv2.rectangle(image, (self.x, self.y), (self.x+self.w, self.y+self.h), color, thickness)
qimage = self.convert_cv_image_to_qt(output_img)
return qimage
def on_click_upload(self):
dialog = QFileDialog()
csv_file = dialog.getOpenFileName(None, "Import CSV", "", "CSV data files (*.csv)")
try:
with open(csv_file[0]) as fp:
reader = csv.reader(fp, delimiter=',')
data = [Row(*r) for r in reader]
except PermissionError:
print("You don't seem to have the rights to open the file")
if 0 == len(data):
print("File is empty, select another file")
return
self.count = 0
self.data = data
upload_image = self.draw_bb_on_image(data[0])
self.label.setPixmap(upload_image)
self.label.show()
def next_image(self, offset=1):
if self.data is None:
return
self.count = (self.count + offset) % len(self.data)
next_image = self.draw_bb_on_image(self.data[self.count])
self.label.setPixmap(next_image)
self.label.show()
def on_click_next(self):
self.next_image(offset=1)
def on_click_previous(self):
self.next_image(offset=-1)
def execute_pipeline():
app = QApplication(sys.argv)
annotationGui = mainProgram()
annotationGui.show()
annotationGui.all_callbacks()
# Exit the window
sys.exit(app.exec_())
if __name__ == "__main__":
execute_pipeline()
我想为对象指定一个名称。为此,我想让这个边界框区域可点击。
【问题讨论】:
-
你如何显示图像?请提供minimal reproducible example。
-
抱歉更新延迟。问题随 MRE 更新。
-
@iamkk 您的问题令人困惑:1)您说图像有多个边界框但.csv 只允许您拥有1 个边界框,您如何获得其他边界框?你能展示一个.csv的样本吗? 2)您的要求令人困惑,据我了解是加载.csv,显示其中一行,单击BB,打开一个对话框,用户在其中设置名称,然后在关闭应用程序时显示信息(文件名, bb 和 name) 在 .csv 中,我正确吗?
-
@eyllanesc 很抱歉造成混乱。 1)让我们考虑一个bb。如果我能够为一个 bb 做到这一点,那么我可以为许多人做相应的修改。因此 .csv 目前只包含一个 bb。 2) 是的,你是对的。
标签: python pyqt5 bounding-box qlabel