I have created a simple GUI in Pyqt to upload a CSV file containing image path and bounding box coordinates values with a push button. And it has another push button which goes to the next image. And the label area to display an image with the bounding box around an object in it as shown below.
Now I would like to assign some name to the object with the bounding box. For this purpose I have another push button. But when there are more than one objects in an image I would like to click on one of the bounding box and then assign the same. But I am struggling to make this bounding box area clickable.
I have seen examples of getting the pixel value or (x, y) when clicked on image but this one seems to be difficult for me.
And code for the same is below.
And the code for the same is as below.
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()
I want to assign a name to the object. For this I would like to make this bounding box area clickable.