class GUIColorTable(QtGui.QWidget): classImageProcess = None processedImagePath = "./images/ball_1_min.png" imageForSearchingPath = "./images/ball_2.png" processedImageMask = None searchedImageSnapshot = None nameForWindowForSelectionPixels = "image for pixels selection" refPT = None #mouseImageLabel = None filteredImageLabel = None contoursImageLabel = None figureImageLabel = None cameraImageLabel = None processedImage = None processedImageClone = None imageForSearching = None imageForSearchingClone = None camera = None def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('Color Table') # Screen Geometry self.screen = QtGui.QDesktopWidget().screenGeometry() # Creation buttons self.addButton = QtGui.QPushButton("Add Color", self) self.addButton.setCheckable(True) self.removeButton = QtGui.QPushButton("Remove color", self) self.removeButton.setCheckable(True) self.takeSnapshotButton = QtGui.QPushButton("Take snapshot", self) # add Event Listeners for Button self.connect(self.addButton, QtCore.SIGNAL('clicked()'), self.setAddColor) self.connect(self.removeButton, QtCore.SIGNAL('clicked()'), self.setRemoveColor) self.connect(self.takeSnapshotButton, QtCore.SIGNAL('clicked()'), self.takeSnapshot) # Creation labels for images #self.mouseImageLabel = QtGui.QLabel() self.filteredImageLabel = QtGui.QLabel() self.contoursImageLabel = QtGui.QLabel() self.figureImageLabel = QtGui.QLabel() #self.mouseImageLabel.mousePressEvent = self.mouseGetPositionDown #self.mouseImageLabel.mouseReleaseEvent = self.mouseGetPosiotionUp #Creation camera label self.cameraImageLabel = QtGui.QLabel() # Creation names for labels #textMouseImage = QtGui.QLabel('Image for selection') textFilteredImage = QtGui.QLabel('Filtered image') textContoursImage = QtGui.QLabel('Image with contours') textShapesImage = QtGui.QLabel('Image with shapes') textCameraImage = QtGui.QLabel('Camera') #Creation images and to labels self.loadImageForSearching(self.imageForSearchingPath) self.loadProcessedImage(self.processedImagePath) # Creation grid grid = QtGui.QGridLayout() grid.setSpacing(10) # Add widgets to grid #grid.addWidget(textMouseImage, 1, 0, 1, 1, QtCore.Qt.AlignTop) grid.addWidget(textCameraImage, 1, 1, 1, 1, QtCore.Qt.AlignTop) grid.addWidget(textFilteredImage, 1, 2, 1, 1, QtCore.Qt.AlignTop) grid.addWidget(textContoursImage, 1, 3, 1, 1, QtCore.Qt.AlignTop) grid.addWidget(textShapesImage, 1, 4, 1, 1, QtCore.Qt.AlignTop) #grid.addWidget(self.mouseImageLabel, 2, 0, 1, 1, QtCore.Qt.AlignCenter) grid.addWidget(self.cameraImageLabel, 2, 1, 1, 1, QtCore.Qt.AlignCenter) grid.addWidget(self.filteredImageLabel, 2, 2, 1, 1, QtCore.Qt.AlignTop) grid.addWidget(self.contoursImageLabel, 2, 3, 1, 1, QtCore.Qt.AlignTop) grid.addWidget(self.figureImageLabel, 2, 4, 1, 1, QtCore.Qt.AlignTop) grid.addWidget(self.addButton, 3, 0, 1, 1, QtCore.Qt.AlignTop) grid.addWidget(self.removeButton, 4, 0, 1, 1, QtCore.Qt.AlignTop) grid.addWidget(self.takeSnapshotButton, 5, 0, 1, 1, QtCore.Qt.AlignTop) self.setLayout(grid) # Set fixed width fot grid self.setFixedWidth(self.screen.width()/1.1) self.center() # Create camera self.camera = Camera(0) self.connect(self.camera, QtCore.SIGNAL('new snapshot'), self.newCapture) self.camera.start() def loadImageForSearching(self, imagePath): self.imageForSearching = cv2.imread(imagePath) self.imageForSearchingClone = copy.copy(self.imageForSearching) self.sizeWidthForImages = (self.screen.width()/1.1)/4 self.filteredImageLabel.setPixmap(self.fromOpenCVImageToQT(self.imageForSearching, self.sizeWidthForImages)) self.contoursImageLabel.setPixmap(self.fromOpenCVImageToQT(self.imageForSearching, self.sizeWidthForImages)) self.figureImageLabel.setPixmap(self.fromOpenCVImageToQT(self.imageForSearching, self.sizeWidthForImages)) def loadProcessedImage(self, imagePath): self.ImageProcess = IPr(imagePath) self.addButton.setChecked(self.ImageProcess.stateAddColor) self.removeButton.setChecked(self.ImageProcess.stateRemoveColor) self.processedImage = cv2.imread(imagePath) self.processedImageClone = copy.copy(self.processedImage) sizeWidth = self.processedImageClone.shape[1] #self.mouseImageLabel.setPixmap(self.fromOpenCVImageToQT(self.processedImage, sizeWidth)) cv2.namedWindow(self.nameForWindowForSelectionPixels) cv2.imshow(self.nameForWindowForSelectionPixels, self.processedImage) cv2.setMouseCallback(self.nameForWindowForSelectionPixels, self.opencvMouseGetPosition) def fromOpenCVImageToQT(self, image, imageWidth): height, width = image.shape[:2] cvRGBImg = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) qimg = QtGui.QImage(cvRGBImg.data, width, height, QtGui.QImage.Format_RGB888) qpm = QtGui.QPixmap.fromImage(qimg).scaledToWidth(imageWidth) return qpm def center(self): screen = QtGui.QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2) def setAddColor(self): if self.addButton.isChecked(): self.ImageProcess.stateAddColor = True self.ImageProcess.stateRemoveColor = False print "add color true" return self.ImageProcess.stateAddColor = False print "add color false" def setRemoveColor(self): if self.removeButton.isChecked(): self.addButton.setChecked(False) self.ImageProcess.stateRemoveColor = True self.ImageProcess.stateAddColor = False print "remove color true" return self.ImageProcess.stateRemoveColor = False print "remove color false" def mouseGetPositionDown(self, event): x = event.pos().x() y = event.pos().y() self.refPT = [(x, y)] def mouseGetPosiotionUp(self, event): x = event.pos().x() y = event.pos().y() self.refPT.append((x, y)) self.processRefPT(self.refPT) def opencvMouseGetPosition(self, event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: self.refPT = [(x, y)] elif event == cv2.EVENT_LBUTTONUP: self.refPT.append((x, y)) self.processRefPT(self.refPT) def processRefPT(self, refPT): if(refPT): changingImage = None colors, changingImage, self.processedImageMask = self.ImageProcess.processColorsByCoordinates(self.refPT) cv2.imshow(self.nameForWindowForSelectionPixels, changingImage) #self.mouseImageLabel.setPixmap(self.fromOpenCVImageToQT(changingImage, changingImage.shape[1])) def newProcessedImage(self, image): self.processedImage = copy.copy(image) self.processedImageClone = copy.copy(image) changingImage, self.processedImageMask = self.ImageProcess.addNewProcessImage(self.processedImageClone) cv2.imshow(self.nameForWindowForSelectionPixels, changingImage) #self.mouseImageLabel.setPixmap(self.fromOpenCVImageToQT(changingImage, changingImage.shape[1])) # Search ball on searching image def searchBall(self, colors, changingImage, mask): changingImage, finalHist = self.equalsHists(self.processedImageClone, mask, self.imageForSearchingClone) changingImage = self.filterImage(changingImage) self.filteredImageLabel.setPixmap(self.fromOpenCVImageToQT(changingImage, self.sizeWidthForImages)) maxContour, changingImage = self.searchContours(changingImage, self.imageForSearchingClone) if len(maxContour) > 0: self.contoursImageLabel.setPixmap(self.fromOpenCVImageToQT(changingImage, self.sizeWidthForImages)) changingImage = self.createCircleAroundContours(self.imageForSearchingClone, maxContour) self.figureImageLabel.setPixmap(self.fromOpenCVImageToQT(changingImage, self.sizeWidthForImages)) def equalsHists(self, processImage, processImageMask, imageForSearching): hist = searchBall.createHistByImage(processImage, processImageMask) maskedImg, finalHist = searchBall.equalsHists(hist, imageForSearching) return maskedImg, finalHist def filterImage(self, image): withoutNoiseImage = searchBall.noiseFilter(image) closedImage = searchBall.closingFilter(withoutNoiseImage) return closedImage def searchContours(self, changingImage, imageForSearching): binary = searchBall.imageToBinary(changingImage) maxContour, imageWithContours = searchBall.searchContoursBinary(binary, imageForSearching) print maxContour return maxContour, imageWithContours def createCircleAroundContours(self, image, contour): return searchBall.getCircleByContours(image, contour) #Get new capture from camera def newCapture(self, frame): self.cameraImageLabel.setPixmap(self.fromOpenCVImageToQT(frame, self.sizeWidthForImages)) self.imageForSearchingClone = copy.copy(frame) if(len(self.ImageProcess.colors) > 0): self.searchBall(self.ImageProcess.colors, self.imageForSearchingClone , self.processedImageMask) def takeSnapshot(self): if len(self.camera.frame) > 0: self.newProcessedImage(self.camera.frame)
class ImageProcessing: classImageProcess = None colorTable = None colorTableMask = None imageForSearching = None clonedImageForSearching = None baseImage = None processImage = None clonedProcessImage = None bgrImage = None hsvImage = None yuvImage = None state = "add" colors = list() refPT = [] def loadImages(self, imageBasePath, imageForSearchingPath): self.classImageProcess = ImageProcess(imageBasePath) self.imageForSearching = cv2.imread(imageForSearchingPath) self.baseImage = cv2.imread(imageBasePath) self.bgrImage = copy.copy(self.baseImage) self.mask = np.zeros(self.baseImage.shape[:2], np.uint8) self.yuvImage = cv2.cvtColor(self.bgrImage, cv2.COLOR_BGR2YUV) self.hsvImage = cv2.cvtColor(self.bgrImage, cv2.COLOR_BGR2HSV) self.processImage = copy.copy(self.bgrImage) self.clonedProcessImage = copy.copy(self.processImage) # cv2.imshow("yuv", self.yuvImage) # cv2.imshow("hsv", self.hsvImage) cv2.imshow("process image", self.processImage) cv2.setMouseCallback("process image", self.mouseEvents) return self.bgrImage def redrawProcessImage(self, colors, baseProcessImage): width, height = baseProcessImage.shape[:2] for y in range(height): for x in range(width): processImagePix = baseProcessImage[x, y] for color in colors: if ( (processImagePix[0] == color[0]) and (processImagePix[1] == color[1]) and (processImagePix[2] == color[2]) ): if self.state == "add": self.mask[x, y] = 255 self.processImage[x, y] = [0, 255, 0] elif self.state == "delete": self.mask[x, y] = 0 self.processImage[x, y] = baseProcessImage[x, y] cv2.imshow("process image", self.processImage) def processColors(self, image, coord): if len(coord) == 2: yCort = (coord[0][1], coord[1][1]) xCort = (coord[0][0], coord[1][0]) yCortMin = min(yCort) yCortMax = max(yCort) xCortMin = min(xCort) xCortMax = max(xCort) newColors = [] if (yCortMin == yCortMax) and (xCortMin == xCortMax): color = list(image[yCortMin, xCortMin]) if color not in self.colors: if self.state == "add": newColors.append(color) self.colors.append(color) else: if self.state == "delete": newColors.append(color) self.colors.remove(color) else: roi = image[yCortMin:yCortMax, xCortMin:xCortMax] width, height = roi.shape[:2] for yRoi in range(height): for xRoi in range(width): color = list(roi[xRoi, yRoi]) if color not in self.colors: if self.state == "add": newColors.append(color) self.colors.append(color) else: if self.state == "delete": newColors.append(color) self.colors.remove(color) print len(self.colors) return newColors def mouseEvents(self, event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: self.refPT = [(x, y)] # self.addToHistPixelSet(self.hsvImage, [y, x]) if event == cv2.EVENT_LBUTTONUP: self.refPT.append((x, y)) self.classImageProcess.processColorsByCoordinates(self.refPT) colors = self.processColors(self.clonedProcessImage, self.refPT) self.redrawProcessImage(colors, self.clonedProcessImage) hist = searchBall.createHistByImage(self.hsvImage, self.mask) maskededImg, finalHist = searchBall.equalsHists(hist, self.imageForSearching) opening = searchBall.noiseFilter(maskededImg) closing = searchBall.closingFilter(opening) binary = searchBall.imageToBinary(closing) contour = searchBall.searchContoursBinary(binary, self.imageForSearching) searchBall.getCircleByContours(self.imageForSearching, contour) print contour