コード例 #1
0
    def __init__(self, name):
        icon_path = tools.getFileInSameDirectory(__file__, 'icon.jpg')
        OTModuleResultsPlugin.__init__(self, name, iconFile=icon_path)

        self._positions = OTParamPositions("Positions")
        self._video = OTParamVideoInput("Video")
        self._player = OTParamPlayer("Video player")
        self._nobjects = OTParamSlider("Number of objects to track", 1, 1, 10)
        self._run = OTParamButton("Run")
        self._apply = OTParamButton("Apply changes")
        self._progress = OTParamProgress()

        #self._query.readOnly = True
        self._run.value = self.run
        self._apply.value = self.apply
        self._video.valueUpdated = self.newVideoInputChoosen
        self._player.processFrame = self.processFrame
        self._query.form.tableView.keyPressEvent = self.keyPressEvent

        self._current_row = None

        self._formset = [('_video', "_positions", '_nobjects', '_run'),
                         '_player', '=', ("_results", '_apply'), "_query",
                         "_progress"]

        self._progress.hide()
コード例 #2
0
    def __init__(self, name):
        icon_path = tools.getFileInSameDirectory(__file__, 'icongeo.png')
        OTBaseModuleGeometry.__init__(self,name, iconFile = icon_path)

        self._imgWidth = 0.0
        self._imgHeight = 0.0
        self._startPoint = None
        self._endPoint = None

        self._selectedPoly = None
        self._selectedPoint = None
        

        self._video  = OTParamVideoInput("Video")
        self._player = OTParamPlayer("Video")
        self._remove = OTParamButton("Remove")
        self._square = OTParamToggle("Square")
        self._circle = OTParamToggle("Circle")
        self._export = OTParamButton("Export")
        self._import = OTParamButton("Import")

        self._formset = [ '_video',"_player", ("_square", "_circle", " ","_remove"," ", "_export", "_import"), "=", "_polygons" ]

        self._video.valueUpdated = self.videoSelected
        self._square.value = self.square_toggle
        self._circle.value = self.circle_toggle
        self._remove.value = self.remove_clicked
        self._export.value = self.export_clicked
        self._import.value = self.import_clicked
        
        self._player._videoWidget.onDrag = self.onDragInVideoWindow
        self._player._videoWidget.onEndDrag = self.onEndDragInVideoWindow
        self._player._videoWidget.onClick = self.onClickInVideoWindow
        self._player._videoWidget.onDoubleClick = self.onDoubleClickInVideoWindow
        self._player.processFrame = self.processFrame
コード例 #3
0
    def __init__(self, name):
        icon_path = tools.getFileInSameDirectory(__file__, 'iconbgcalc.jpg')
        OTModulePlugin.__init__(self, name, iconFile=icon_path)

        self._video = OTParamVideoInput("Video")

        self._jumpFrame = OTParamSlider("Frame jump step", 1000, 1, 4000)
        self._jump2Frame = OTParamSlider("Compare frame", 1500, 1, 4000)
        self._threshold = OTParamSlider("Threshold", 5, 0, 255)

        self._export = OTParamButton("Export")

        self._editMode = OTParamCheckBox("Edit mode", False)
        self._run = OTParamButton("Run")
        self._player = OTParamPlayer("Video player")
        self._progress = OTParamProgress()

        self._formset = [('_video', '_run', '_editMode', '_export'),
                         ('_jumpFrame', '_jump2Frame', '_threshold'),
                         "_player", "_progress"]

        self._run.value = self.run
        self._player.processFrame = self.processFrame
        self._video.valueUpdated = self.newVideoInputChoosen

        self._export.value = self.export_clicked

        self._backgroundDetector = None
        self._progress.hide()
コード例 #4
0
    def __init__(self, name):
        icon_path = tools.getFileInSameDirectory(__file__, 'centre.png')
        super(OTModuleCircleCenter, self).__init__(name, iconFile=icon_path)

        self._video = OTParamVideoInput("Video")
        self._player = OTParamPlayer("Video")
        self._run = OTParamButton("Run")

        self._formset = [('_video', '_run'), "_player"]

        self._video.valueUpdated = self.videoSelected
        self._run.value = self.__run

        self._center = None
        self._player.processFrame = self.processFrame
コード例 #5
0
    def __init__(self, name):
        icon_path = tools.getFileInSameDirectory(__file__, 'radius.png')
        OTBaseModuleGeometry.__init__(self, name, iconFile=icon_path)

        self._video = OTParamVideoInput("Video")
        self._circlecenter = OTParamModuleConnection(
            "Circle center", connecting=OTModuleCircleCenter)
        self._player = OTParamPlayer("Video")
        self._run = OTParamButton("Run")

        self._formset = [('_video', '_circlecenter', '_run'), "_player", "=",
                         '_polygons']

        self._video.valueUpdated = self.videoSelected
        self._run.value = self.__run

        self._radius = None
        self._player.processFrame = self.processFrame
コード例 #6
0
    def __init__(self, name):
        icon_path = tools.getFileInSameDirectory(__file__, 'iconsubbg.jpg')
        OTPRemoveBackground.__init__(self)
        OTPColorFilter.__init__(self)
        OTPBlur.__init__(self)
        OTPFindBlobs.__init__(self)
        OTPSelectBiggerBlobs.__init__(self)
        OTModuleResultsPlugin.__init__(self, name, iconFile=icon_path)

        self._video = OTParamVideoInput("Video")
        self._background = OTParamBackground("Background",
                                             varname='_param_background')
        self._threshold = OTParamSlider("Threshold",
                                        110,
                                        1,
                                        255,
                                        varname='_param_background_threshold')
        self._minArea = OTParamSlider("Blob min. area",
                                      100,
                                      0,
                                      50000,
                                      varname='_param_min_area')
        self._maxArea = OTParamSlider("Blob max. area",
                                      10000,
                                      0,
                                      100000,
                                      varname='_param_max_area')
        self._textAlgo = OTParamText(
            "Blob function ( Operations: [ AND: * ; OR: + ; SUB: - ; NEG: ~ ] Ex: A+B-~C )",
            "A*B*C",
            varname='_param_filter_algorithm')
        self._removeBg = OTParamCheckBox("Remove the background", True)
        self._editMode = OTParamCheckBox("Edit mode", True)
        self._run = OTParamButton("Run")
        self._player = OTParamPlayer("Video player")
        self._progress = OTParamProgress()

        self._selectBiggests = OTParamCheckBox(
            "Select only the biggests blobs", True)
        self._howMany = OTParamSlider("How many?",
                                      1,
                                      1,
                                      20,
                                      varname='_param_n_blobs')

        self._useBlur = OTParamCheckBox("Use blur", True)
        self._kernelSize = OTParamSlider("Kernel size",
                                         1,
                                         1,
                                         50,
                                         varname='_param_kernel_size')
        self._blurThreshold = OTParamSlider("Blur threshold",
                                            110,
                                            1,
                                            255,
                                            varname='_param_blur_threshould')

        self._colorDomain = OTParamCombo("Colors space",
                                         varname='_param_color_domain')
        self._colorDomain.addItem("RGB", -1)
        self._colorDomain.addItem("XYZ", cv2.COLOR_BGR2XYZ)
        self._colorDomain.addItem("YCrCb", cv2.COLOR_BGR2YCR_CB)
        self._colorDomain.addItem("HSV", cv2.COLOR_BGR2HSV)
        self._colorDomain.addItem("HLS", cv2.COLOR_BGR2HLS)
        self._colorDomain.addItem("Lab", cv2.COLOR_BGR2LAB)
        self._colorDomain.addItem("Luv", cv2.COLOR_BGR2LUV)

        self._activeR = OTParamCheckBox("Active")
        self._activeG = OTParamCheckBox("Active")
        self._activeB = OTParamCheckBox("Active")

        self._minR = OTParamSlider("min. A", 1, 0, 255, varname='_param_a_min')
        self._maxR = OTParamSlider("max. A",
                                   255,
                                   0,
                                   255,
                                   varname='_param_a_max')
        self._minG = OTParamSlider("min. B", 1, 0, 255, varname='_param_b_min')
        self._maxG = OTParamSlider("max. B",
                                   255,
                                   0,
                                   255,
                                   varname='_param_b_max')
        self._minB = OTParamSlider("min. C", 1, 0, 255, varname='_param_c_min')
        self._maxB = OTParamSlider("max. C",
                                   255,
                                   0,
                                   255,
                                   varname='_param_c_max')

        self._groupBlobs = OTParamCheckBox("Group blobs", True)
        self._maxDistance = OTParamSlider("Max. dist. between blobs", 1, 30,
                                          300)

        self._groupBlobs.valueUpdated = self.groupBlobsUpdated
        self._colorDomain.valueUpdated = self.refreshValue

        self._activeR.valueUpdated = self.refreshValue
        self._activeG.valueUpdated = self.refreshValue
        self._activeB.valueUpdated = self.refreshValue

        self._minR.valueUpdated = self.refreshValue
        self._maxR.valueUpdated = self.refreshValue
        self._minG.valueUpdated = self.refreshValue
        self._maxG.valueUpdated = self.refreshValue
        self._minB.valueUpdated = self.refreshValue
        self._maxB.valueUpdated = self.refreshValue

        self._textAlgo.valueUpdated = self.refreshValue
        self._threshold.valueUpdated = self.refreshValue
        self._kernelSize.valueUpdated = self.refreshValue
        self._blurThreshold.valueUpdated = self.refreshValue
        self._maxArea.valueUpdated = self.refreshValue
        self._minArea.valueUpdated = self.refreshValue
        self._maxDistance.valueUpdated = self.refreshValue

        self._removeBg.valueUpdated = self.removeBgUpdate
        self._useBlur.valueUpdated = self.useBlurUpdate
        self._selectBiggests.valueUpdated = self.selectBiggestsUpdate

        self._formset = [
            ('_video', '_editMode', '_run'),
            [
                "_player", {
                    "1. Filter colors": [
                        '_colorDomain', ("_minR", '_activeR', "_maxR"),
                        ("_minG", '_activeG', "_maxG"),
                        ("_minB", '_activeB', "_maxB"), "_textAlgo"
                    ],
                    "2. Remove background":
                    ['_removeBg', '_background', '_threshold'],
                    "3. Filter objects":
                    [('_minArea', '_maxArea'),
                     ('_useBlur', '_kernelSize', '_blurThreshold'),
                     ("_selectBiggests", "_howMany")],
                    "4. Tracking": [('_groupBlobs', '_maxDistance')],
                }, "=", "_results", "_query"
            ], "_progress"
        ]

        self._run.value = self.run
        self._player.processFrame = self.processFrame
        self._video.valueUpdated = self.newVideoInputChoosen

        self._isRunning = False

        self._blurThreshold.hide()
        self._kernelSize.hide()
        self._background.hide()
        self._threshold.hide()
        self._progress.hide()
        self._howMany.hide()
        self._results.hide()
        self._query.hide()
        self._maxDistance.hide()
コード例 #7
0
    def __init__(self, name):
        icon_path = tools.getFileInSameDirectory(__file__, 'icon.jpg')
        OTModuleResultsPlugin.__init__(self, name, iconFile = icon_path)

        self._x_col = 4 #Indicate the column with the X coord
        self._y_col = 5 #Indicate the column with the Y coord
        self._frame_col = 1 #Indicate the column with the Y coord
        self._object_col = 6
        self._current_row = None

        self._imgWidth = 0.0
        self._imgHeight = 0.0
        self._startPoint = None
        self._endPoint = None

        self._video = OTParamVideoInput("Video")
        self._positions = OTParamPositions("Positions")
        self._showPos = OTParamCheckBox("Show position")
        self._showTrack = OTParamCheckBox("Show track")
        self._trackRange = OTParamSlider("Track range", 10, 10, 1000)
        self._player = OTParamPlayer("Video player")
        self._progress = OTParamProgress()
        
        #Fields used to configure the Position draw function
        self._show_draw_function = OTParamToggle("Show/Hide draw function")
        self._draw_function = OTParamTextArea("Draw function", """def draw(frame, row):
            x, y = int(row[self._x_col]), int(row[self._y_col])
            cv2.circle(frame, (x, y), 3, (0,255,0), thickness=2, lineType= cv2.cv.CV_AA)""")
        self._importFunc = OTParamButton("Import")
        self._exportFunc = OTParamButton("Export")
        
        #Fields used to configure the interpolation
        self._columns = OTParamCheckBoxList("List of columns to interpolate")
        self._run_interpolation = OTParamButton("Interpolate")
        self._run_interpolation_4_all = OTParamButton("Interpolate")

        #organization of the form
        self._formset = [   ('_video','_positions'), 
            [ ('_columns', '_run_interpolation', '_run_interpolation_4_all'),
            "_draw_function", 
            (" ", "_importFunc", "_exportFunc"), 
            "_player",
            ('_showPos',"_showTrack", "_trackRange")
            ,"=","_results", "_query"], '_progress' ]

        self._trackRange.enabled = False
        self._showPos.value = True

        #setting up the fields events
        self._player.processFrame = self.processFrame
        self._video.valueUpdated = self.newVideoInputChoosen
        self._positions.valueUpdated = self.newPositionsChoosen
        self._showTrack.valueUpdated = self.showTrackToggle
        self._query.selectionChanged = self.tableSelectionChanged
        self._trackRange.valueUpdated = self.updateTrackRange
        self._player._videoWidget.onEndDrag = self.onEndDragInVideoWindow
        self._show_draw_function.value = self.showHideDrawFunction
        self._importFunc.value = self.importFunction
        self._exportFunc.value = self.exportFunction
        self._run_interpolation.value = self.interpolationPositions
        self._run_interpolation_4_all.value = self.interpolateAllPositions

        #Hide fields
        self._draw_function.hide()
        self._progress.hide()
        self._importFunc.hide()
        self._exportFunc.hide()
        self._columns.hide()
        self._run_interpolation.hide()
        self._run_interpolation_4_all.hide()
        
        #Configure the popup menu
        self._query.addPopupMenuOption("-")
        self._query.addPopupSubMenuOption("Add", {"Interpolation": self.showColumns4Interpolation, "Duplicate row": self.addDuplicatedRow })
        self._query.addPopupMenuOption("Remove", self._query.remove)
        self._query.addPopupMenuOption("-")
        self._query.addPopupMenuOption("Approximate all positions", self.approximatePositions)
        self._query.addPopupMenuOption("Interpolate all positions", self.showColumns4InterpolationAll)
        
        self._current_row_index = None #Variable used to read the current row when the video is playing
コード例 #8
0
class OTModuleAdjustPositions(OTModuleResultsPlugin, OTModulePositions):

    

    def __init__(self, name):
        icon_path = tools.getFileInSameDirectory(__file__, 'icon.jpg')
        OTModuleResultsPlugin.__init__(self, name, iconFile = icon_path)

        self._x_col = 4 #Indicate the column with the X coord
        self._y_col = 5 #Indicate the column with the Y coord
        self._frame_col = 1 #Indicate the column with the Y coord
        self._object_col = 6
        self._current_row = None

        self._imgWidth = 0.0
        self._imgHeight = 0.0
        self._startPoint = None
        self._endPoint = None

        self._video = OTParamVideoInput("Video")
        self._positions = OTParamPositions("Positions")
        self._showPos = OTParamCheckBox("Show position")
        self._showTrack = OTParamCheckBox("Show track")
        self._trackRange = OTParamSlider("Track range", 10, 10, 1000)
        self._player = OTParamPlayer("Video player")
        self._progress = OTParamProgress()
        
        #Fields used to configure the Position draw function
        self._show_draw_function = OTParamToggle("Show/Hide draw function")
        self._draw_function = OTParamTextArea("Draw function", """def draw(frame, row):
            x, y = int(row[self._x_col]), int(row[self._y_col])
            cv2.circle(frame, (x, y), 3, (0,255,0), thickness=2, lineType= cv2.cv.CV_AA)""")
        self._importFunc = OTParamButton("Import")
        self._exportFunc = OTParamButton("Export")
        
        #Fields used to configure the interpolation
        self._columns = OTParamCheckBoxList("List of columns to interpolate")
        self._run_interpolation = OTParamButton("Interpolate")
        self._run_interpolation_4_all = OTParamButton("Interpolate")

        #organization of the form
        self._formset = [   ('_video','_positions'), 
            [ ('_columns', '_run_interpolation', '_run_interpolation_4_all'),
            "_draw_function", 
            (" ", "_importFunc", "_exportFunc"), 
            "_player",
            ('_showPos',"_showTrack", "_trackRange")
            ,"=","_results", "_query"], '_progress' ]

        self._trackRange.enabled = False
        self._showPos.value = True

        #setting up the fields events
        self._player.processFrame = self.processFrame
        self._video.valueUpdated = self.newVideoInputChoosen
        self._positions.valueUpdated = self.newPositionsChoosen
        self._showTrack.valueUpdated = self.showTrackToggle
        self._query.selectionChanged = self.tableSelectionChanged
        self._trackRange.valueUpdated = self.updateTrackRange
        self._player._videoWidget.onEndDrag = self.onEndDragInVideoWindow
        self._show_draw_function.value = self.showHideDrawFunction
        self._importFunc.value = self.importFunction
        self._exportFunc.value = self.exportFunction
        self._run_interpolation.value = self.interpolationPositions
        self._run_interpolation_4_all.value = self.interpolateAllPositions

        #Hide fields
        self._draw_function.hide()
        self._progress.hide()
        self._importFunc.hide()
        self._exportFunc.hide()
        self._columns.hide()
        self._run_interpolation.hide()
        self._run_interpolation_4_all.hide()
        
        #Configure the popup menu
        self._query.addPopupMenuOption("-")
        self._query.addPopupSubMenuOption("Add", {"Interpolation": self.showColumns4Interpolation, "Duplicate row": self.addDuplicatedRow })
        self._query.addPopupMenuOption("Remove", self._query.remove)
        self._query.addPopupMenuOption("-")
        self._query.addPopupMenuOption("Approximate all positions", self.approximatePositions)
        self._query.addPopupMenuOption("Interpolate all positions", self.showColumns4InterpolationAll)
        
        self._current_row_index = None #Variable used to read the current row when the video is playing

    def onEndDragInVideoWindow(self, startPoint, endPoint, refresh=True):
        self._startPoint = ( int(startPoint[0] * self._imgWidth), int(startPoint[1] * self._imgWidth) )
        self._endPoint = ( int(endPoint[0] * self._imgWidth), int(endPoint[1] * self._imgWidth) )

        current_row = self._query.mouseSelectedRow

        if current_row!=None:
            current_index = self._query.mouseSelectedRowIndex
            current_frame = int(current_row[self._frame_col])
            if (self._player.value.getCurrentFrame()) == current_frame:
                x, y = int(current_row[self._x_col]), int(current_row[self._y_col])
                #print "current_row", self._startPoint, x, y
                    
                if tools.pointsDistance( self._startPoint , (x,y) ) <= 10:
                    self._query.setValueIn( current_index, self._x_col, self._endPoint[0] )
                    self._query.setValueIn( current_index, self._y_col, self._endPoint[1] )
                    self._current_row = self._query.valuesInRow(current_index)
                    if refresh: 
                        self._query.commit()
                        self._player.refresh()
                        self._query.refresh( current_index )
                        self._query.select()

    def exportFunction(self):
        filename = str(QFileDialog.getSaveFileName(self._form, 'Choose a file', '') )
        if filename!="":
            output = open( filename, 'wb')
            pickle.dump( self._draw_function.value , output)
            output.close()

    def importFunction(self):
        filename = str(QFileDialog.getOpenFileName(self._form, 'Choose a file', '') )
        if filename!="":
            pkl_file = open( filename, 'rb'); data = pickle.load(pkl_file); pkl_file.close()
            self._draw_function.value = data
            func = self._draw_function.value
            exec func
            self.drawRow = draw

    def showHideDrawFunction(self, value):
        if value:
            self._player.hide()
            self._importFunc.show()
            self._exportFunc.show()
            self._draw_function.show()
        else:
            self._draw_function.hide()
            self._importFunc.hide()
            self._exportFunc.hide()
            self._player.show()

            func = self._draw_function.value
            #code = compile(func, '<string>', 'exec')
            exec func
            self.drawRow = draw
            

            """d = {}
            exec func.strip() in d
            print d
            setattr(self.__class__, 'drawRow', d['drawRow'])
            """
            #self.drawRow = eval( func)




    def approximatePositions(self):
        totalCountRows = self._query.count
        firstRow = self._query.valuesInRow( totalCountRows-1 )

        firstPoint = ( int(firstRow[self._x_col]), int(firstRow[self._y_col]) )
        lastAngle = None

        self._progress.show()
        self._progress.min = 0
        self._progress.value = 0
        self._progress.max = totalCountRows

        query = QSqlQuery( self.parentModule.sqldb )
        
        self._query.beginTransaction()
        for i in range( totalCountRows-2, 0, -1 ):            #print i
            currentRow = self._query.valuesInRow( i )
            currentPoint = ( int(currentRow[self._x_col]), int(currentRow[self._y_col]) )
            dist = tools.pointsDistance( firstPoint, currentPoint )
            vector = ( firstPoint[0]-currentPoint[0], firstPoint[1]-currentPoint[1] )
            angle = math.atan2( vector[1], vector[0] )
            angleInDegrees = math.degrees( angle )

            frame = currentRow[self._frame_col]
            obj = currentRow[self._object_col]

            #print "angle:---", angleInDegrees, lastAngle
            if lastAngle==None: lastAngle=angleInDegrees
            if dist<=10: 
                #self._query.removeRow( i )
                #print "DELETE FROM %s WHERE frame='%s' and object='%s' " % (self._query.table, frame, obj )
                query.exec_("DELETE FROM %s WHERE frame='%s' and object='%s' " % (self._query.table, frame, obj ) )
            elif( math.fabs(lastAngle-angleInDegrees)>=5 ): 
                #print "angles", angleInDegrees, lastAngle
                firstPoint = currentPoint
                lastAngle = angleInDegrees
            else:
                #print "DELETE FROM %s WHERE frame='%s' and object='%s' " % (self._query.table, frame, obj )
                query.exec_("DELETE FROM %s WHERE frame='%s' and object='%s' " % (self._query.table, frame, obj ) )
                #self._query.removeRow( i )


            self._progress.value = totalCountRows - i
            QApplication.processEvents()

        self._query.commit()
        self._progress.hide()
        self._query.refresh(0)


    def showTrackToggle(self, value):
        self._trackRange.enabled = value
   

    def  updateTrackRange(self, value):
        if isinstance(self._player.value, OTVideoInput): self._player.refresh()
        

    ############################################################################
    ############ Parent class functions reemplementation #######################
    ############################################################################

    def selectionChanged(self, selected, deselected):
        """
        Redefinition of the function selectionChanged from OTModuleResultsPlugin
        """
        QTableView.selectionChanged(self._query.form.tableView, selected, deselected)
        row = self._query.mouseSelectedRow
        if row != None:
            self._current_row = row
            video = self._video.value
            frame_index = int( row[self._frame_col] )
            video.videoInput.setFrame( frame_index-1 )
            self._player.updateFrame()

    ############################################################################
    ############ Events ########################################################
    ############################################################################

    def updateProgressBar(self, index): self._progress.value = index

    def interpolateAllPositions(self):
        """
        Event called when user click in interpolation button
        """
        self._run_interpolation.hide()
        self._run_interpolation_4_all.hide()
        self._columns.hide()        
        self._player.show()
        
        totalCountRows = self._query.count
        n_columns = len(self._query.columns)
        checked_columns = self._columns.checkedIndexes
        cols_2_interpolate = map( lambda x: True if x in checked_columns else False, range(n_columns) )
        
        self._progress.show()
        self._progress.min = 0
        self._progress.value = 0
        self._progress.max = totalCountRows
        
        for i in range( 0, totalCountRows-1 ):
            self.interpolateBetween2Rows( i, i+1, update = self.updateProgressBar ,cols_2_interpolate = cols_2_interpolate )
            self._query.commit()     
            self._progress.value = i
           
        self._progress.hide()
        self._query.orderBy = 1

  

    def interpolationPositions(self):
        """
        Event called when user click in interpolation button
        """
        self._run_interpolation.hide()
        self._run_interpolation_4_all.hide()
        self._columns.hide()        
        self._player.show()

        rowsIndexes = self._query.mouseSelectedRowsIndexes
        rowsIndexes.sort()
        if len(rowsIndexes)==2 and rowsIndexes[0]==rowsIndexes[1]-1: #check is the rows are consecutives
            rows = self._query.mouseSelectedRows
            diff = float(abs( int(rows[1][0]) - int(rows[0][0]) ))
            if diff > 1 :
                print rowsIndexes[0], rowsIndexes[1] 
                self.interpolateBetween2Rows( rowsIndexes[0], rowsIndexes[1], update = self.updateProgressBar  )
                self._query.commit()
                self._query.orderBy = 1
                self._query.mouseSelectedRowsIndexes = rowsIndexes[0]
            else:
                QMessageBox. warning(self._form, 'Warning', "Is not possible to add more frames between the selected ones")
        else:
            QMessageBox. warning(self._form, 'Warning', "You should select two consecutive rows")
        

    def addDuplicatedRow(self):
        """
        Event called when a user click on the popup menu option
        """
        rows = self._query.mouseSelectedRows
        rowsIndexes = self._query.mouseSelectedRowsIndexes
        if len(rows)==1:
            lastRow = rows[-1]
            self._query.addRow(lastRow, rowsIndexes[0])
        else:
            QMessageBox. warning(self._control, 'Warning', "You should select one row to duplicate")
        self._query.orderBy = 1
        self._query.mouseSelectedRowsIndexes = rowsIndexes[0]

    def showColumns4Interpolation(self):
        """
        Event called when a user click on the popup menu option
        """
        self._player.hide()
        self._draw_function.hide()
        self._exportFunc.hide()
        self._importFunc.hide()
        self._run_interpolation_4_all.hide()

        self._columns.show()
        self._run_interpolation.show()


    def showColumns4InterpolationAll(self):
        """
        Event called when a user click on the popup menu option
        """
        self._player.hide()
        self._draw_function.hide()
        self._exportFunc.hide()
        self._importFunc.hide()
        self._run_interpolation.hide()

        self._columns.show()
        self._run_interpolation_4_all.show()


    def tableSelectionChanged(self):
        """
        Event called when a user select rows using the popup menu
        """
        self._player.refresh()

    def newVideoInputChoosen(self, value):
        """
        Event called when a user select rows using the popup menu
        @param value: Video module
        @type value: OTModule
        """
        OTParamVideoInput.valueUpdated(self._video,value)
        if value.videoInput:
            value.videoInput.setFrame(0)
            self._player.value = value.videoInput
            self._imgWidth = float(value.videoInput.width)
            self._imgHeight = float(value.videoInput.height)            
            self._trackRange.max = value.videoInput.endFrame-value.videoInput.startFrame

    def newPositionsChoosen(self, value):
        """
        Event called when a new dataset of Positions is choosen
        @param frame: Frame that would be showed
        @type frame: Numpy array
        """
        if value:
            items = value._results.values
            self._results.clearItems()
            for key, sql in items: self._results.addItem(key, sql)

            self._columns.clear()
            list_of_columns = self._query.columns
            self._columns.value = map(lambda x: (x, False), list_of_columns)
            
            self._x_col = self._query.columnIndex("x")
            self._y_col = self._query.columnIndex("y")
            self._frame_col = self._query.columnIndex("frame")

    def processFrame(self, frame, drawSelectedRows = True):
        """
        This is an event called by the player before he shows the video frame
        @param frame: Frame that would be showed
        @type frame: Numpy array
        """

        #Draw the path of the rat
        if self._showTrack.value:
            row_index = self._query.mouseSelectedRowIndex
            if row_index!=None:
                points = []
                for row in range(row_index, row_index + self._trackRange.value):
                    values = self._query.valuesInRow(row)
                    if values!= None:
                        x = int(values[self._x_col])
                        y = int(values[self._y_col])
                        points.append( (x,y) )
                if len(points)>0: cv2.polylines( frame , [array(points,int32)] , False, (255,255,0), 1, lineType=cv2.cv.CV_AA )
            

        #draw the selected path
        #When the rows are selected with the popup menu in the Table
        if drawSelectedRows:
            selectedRows = self._query.selectedRows
            if len( selectedRows )>0:
                track_points = []
                for row in selectedRows:
                    values = self._query.valuesInRow(row)
                    x = int(values[self._x_col])
                    y = int(values[self._y_col])
                    track_points.append( (x,y) )
                cv2.polylines(frame, [array(track_points,int32)], False, (0,255,0), 1)
                for point in track_points: cv2.circle(frame, point, 3, (0,0,255), thickness=1, lineType= cv2.cv.CV_AA)


        #Draw the current mouse selected row
        if self._current_row != None  and self._showPos.value: frame = self.drawRow( frame, self._current_row, (0,0,255) )
            
        if self._player.is_playing(): self.drawCurrentPositionWhenIsPlaying(frame)

        return frame


    ############################################################################
    ############ Functions #####################################################
    ############################################################################

    def search_4_frame(self, frame2Search, startAtRow = 0):
        """
        This function search for a frame in the List _query
        @param frame2Search: Frame to search
        @type frame2Search: Integer
        @param startAtRow: Start looking in the List row index
        @type startAtRow: Integer
        """

        if startAtRow<0: startAtRow=0
        total_count_rows = self._query.count
        
        if total_count_rows==0: # No rows
            return None
        elif total_count_rows==1: #If only one row
            unique_row = self._query.valuesInRow( 0 )
            frame = int(unique_row[self._frame_col])
            if frame > frame2Search: return 0, None, unique_row, None
            else: return None, 0, None, unique_row
        elif startAtRow >= total_count_rows: # In case of start searching in a non existing row
            last_row = self._query.valuesInRow( total_count_rows-1 )
            return total_count_rows-1, None, last_row, None
        else:
            #check the next row
            previous_row    = self._query.valuesInRow( startAtRow )
            next_row        = self._query.valuesInRow( startAtRow + 1 )
            if previous_row!=None and next_row!=None: #check the current row
                previous_frame  = int(previous_row[self._frame_col])
                next_frame      = int(next_row[self._frame_col])
                if previous_frame<=frame2Search<next_frame: 
                    return startAtRow, startAtRow+1, previous_row, next_row
                else: #check the next row
                    previous_row    = self._query.valuesInRow( startAtRow+1 )
                    next_row        = self._query.valuesInRow( startAtRow+2 )
                    if previous_row!=None and next_row!=None:
                        previous_frame  = int(previous_row[self._frame_col])
                        next_frame      = int(next_row[self._frame_col])
                        if previous_frame<=frame2Search<next_frame: 
                            return startAtRow+1, startAtRow+2, previous_row, next_row

            #check if the frame to search is bellow the first row and higher than the last frame
            first_row = self._query.valuesInRow( 0 )
            first_frame = int(first_row[self._frame_col])
            last_row = self._query.valuesInRow( total_count_rows-1 )
            last_frame = int(last_row[self._frame_col])
            if first_frame>=frame2Search: 
                return None, 0, None, first_row
            elif frame2Search>=last_frame:
                return total_count_rows-1, None, last_row, None
            else:
                #Give up!!!! ....Start a binary tree search
                previous_row_index  = 0
                next_row_index      = (total_count_rows+1)/2
                count = 0
                # search for the frame
                calculateSize = True
                while True:
                    if count > 10000: # for security. We don't want the algorithm to enter in a infinite loop
                        return None 
                    if calculateSize: sizeOfList2Search = (next_row_index - previous_row_index)
                    calculateSize = True

                    next_row            = self._query.valuesInRow( next_row_index )
                    next_frame          = int( next_row[self._frame_col] )

                    previous_row        = self._query.valuesInRow( previous_row_index )
                    previous_frame      = int( previous_row[self._frame_col] )

                    if sizeOfList2Search==1 and previous_frame <= frame2Search < next_frame:
                        return previous_row_index, next_row_index, previous_row, next_row
                    elif sizeOfList2Search<1:
                        return None
                    elif previous_frame==frame2Search:
                        return previous_row_index, previous_row_index+1, previous_row, self._query.valuesInRow( previous_row_index+1 )
                    elif next_frame <= frame2Search and sizeOfList2Search>1:
                        previous_row_index = next_row_index
                        next_row_index += (sizeOfList2Search+1)/2
                        if next_row_index>=total_count_rows: next_row_index = total_count_rows-1
                    elif previous_frame < frame2Search < next_frame and sizeOfList2Search>1:
                        next_row_index -= (sizeOfList2Search+1)/2
                        if next_row_index<0: next_row_index = previous_row_index+1
                        calculateSize = False
                    else:
                        count += 1


                
    def drawCurrentPositionWhenIsPlaying( self, frame ):
        current_frame = self._player.value.getCurrentFrame()
        res = self.search_4_frame( current_frame, self._current_row_index )
        
        if res!=None and self._showPos.value:
            previous_index, next_index, previous_row, next_row = res

            row = None
            if previous_row==None:
                self._current_row_index = 0
                row = next_row
                x, y = int(row[self._x_col]), int(row[self._y_col])
            elif next_row==None:
                self._current_row_index = previous_index
                row = previous_row
                x, y = int(row[self._x_col]), int(row[self._y_col])
            else:
                row = previous_row
                prev_x, prev_y = float(previous_row[self._x_col]), float(previous_row[self._y_col])
                next_x, next_y = float(next_row[self._x_col]), float(next_row[self._y_col])
                prev_frame, next_frame = int(previous_row[0]), int(next_row[0])
                nSteps = float(next_frame - prev_frame)
                xStep, yStep = (next_x-prev_x)/nSteps, (next_y-prev_y)/nSteps
                nSteps2CurrentFrame = float(current_frame-prev_frame)
                x, y = xStep*nSteps2CurrentFrame, yStep*nSteps2CurrentFrame
                x, y = int(round( prev_x + x )), int(round( prev_y + y ))

            #row[self._x_col], row[self._y_col] = x, y
            #frame = self.drawRow( frame, row, (255,0,0) )
            cv2.circle(frame, (x,y), 3, (255,0,0), 2)
        return frame


    def drawRow(self, frame, row, color = (0,255,0) ):
        x, y = int(row[self._x_col]), int(row[self._y_col])
        cv2.circle(frame, (x, y), 3, color, thickness=2, lineType= cv2.cv.CV_AA)
        return frame


    def interpolateBetween2Rows(self, row1, row2, update = (lambda x: 0), cols_2_interpolate = None ):
        """
        Interpolate values between 2 rows
        @param row1: First row
        @type row1: Integer
        @param row2: First row
        @type row2: Integer
        """
        if cols_2_interpolate==None:
            checked_columns = self._columns.checkedIndexes
            n_columns = len(self._query.columns)
            cols_2_interpolate = map( lambda x: True if x in checked_columns else False, range(n_columns) )
        else:
            n_columns = len(cols_2_interpolate)
        
        previous_row = self._query.valuesInRow( row1 )
        next_row = self._query.valuesInRow( row2 )    
        previous_frame = int( previous_row[self._frame_col] )
        next_frame = int( next_row[self._frame_col] )
        diff_frames = float( next_frame - previous_frame )
        if diff_frames>1:
            previous, next, diff, step = [], [], [], []
            for i in range(n_columns): 
                if cols_2_interpolate[i]:
                    previous.append(    float(previous_row[i]) )
                    next.append(        float(next_row[i])     )
                    diff = float(next[i]) - float(previous[i])
                    step.append( diff / diff_frames )                        
                else: 
                    step.append( None )
                    previous.append(    previous_row[i] )
                    next.append(        next_row[i]     )

            for j in range(1, int(diff_frames)):
                values = []
                for i in range(n_columns):
                    if cols_2_interpolate[i]:
                        if int(previous[i])==previous[i] and int(next[i])==next[i]:
                            val = int(previous[i]) + int(round( step[i]* float(j) ))
                        else:
                            val = previous[i] + step[i]*float(j)
                    else: val = previous[i]
                    values.append( val )
                update( row1 + j )

                values.pop(0)
                self._query.addRow( values, -1,cols= [ 'frame', 'seconds','milliseconds', 'x', 'y', 'object' ])
                QApplication.processEvents()