def perform(mat, a): if not mat.empty(): imgproc.GaussianBlur(mat, tmp, core.Size(99), 16.0) core.absdiff(mat, tmp, tmp) imgproc.threshold(tmp, tmp, a, 255, imgproc.THRESH_BINARY) imgproc.GaussianBlur(tmp, tmp, core.Size(99), 2.0) return tmp else: return mat
CorrMapImp.show() # Threshold the corrmap (below threshold 0, above left untouched) if Method == 1: # Invert the correlation map : min becomes maxima One = Scalar(1.0) CorrMapInvCV = subtract(One, CorrMapCV).asMat() #CorrMapInv = MatToImProc(CorrMapInvCV) #CorrMapInv = ImagePlus("Inverted", CorrMapInv) #CorrMapInv.show() # Apply a "TO ZERO" threshold on the correlation map : to compensate the fact that maxima finder does not have a threshold argument # TO ZERO : below the threshold set to 0, above left untouched # NB : 1-score_threshold since we have inverted the image : we want to look for minima of value <x so we have to look for maxima of value>1-x in the inverted image CorrMapThreshCV = Mat() threshold(CorrMapInvCV, CorrMapThreshCV, 1 - score_threshold, 0, CV_THRESH_TOZERO) #CorrMapThreshImp = ImagePlus("Thresholded", CorrMapThresh) #CorrMapThreshImp.show() else: CorrMapThreshCV = Mat() threshold(CorrMapCV, CorrMapThreshCV, score_threshold, 0, CV_THRESH_TOZERO) # Display CorrMapThresh = MatToImProc( CorrMapThreshCV) # Keep this conversion, not only for visualisation CorrMapThreshImp = ImagePlus("Score Map - thresholded", CorrMapThresh) CorrMapThreshImp.show() ## For both cases (Multi-Min/Max-detection) detect maxima on the thresholded map excludeOnEdge = False # otherwise miss quite a lot of them
def FindMinMax(CorrMapCV, Unique=True, MinMax="Max", Score_Threshold=0.5, Tolerance=0): ''' Detect Minima(s) or Maxima(s) in the correlation map The function uses for that the MinMaxLoc from opencv for unique detection or the MaximumFinder from ImageJ for multi-detection (in this case, for min detection the correlation map is inverted) - Unique : True if we look for one global min/max, False if we want local ones - MinMax : "Min" if we look for Minima, "Max" if we look for maxima - Score_Threshold : in range [0;1] (correlation maps are normalised) - Tolerance : Parameters for flood-fill. Not used here so should be set to 0 Returns List of Min/Max : [(X, Y, Coefficient), ... ] ''' #### Detect min/maxima of correlation map #### Extrema = [] ## if 1 hit expected if Unique: # Look for THE global min/max minVal = DoublePointer(1) maxVal = DoublePointer(1) minLoc = Point() maxLoc = Point() minMaxLoc(CorrMapCV, minVal, maxVal, minLoc, maxLoc, Mat()) if MinMax=="Min": # For method based on difference we look at the min value X = minLoc.x() Y = minLoc.y() Coeff = minVal.get() elif MinMax=="Max": X = maxLoc.x() Y = maxLoc.y() Coeff = maxVal.get() # Append to the output list Extrema.append( (X, Y, Coeff) ) ## if more hit expected else: # expect more than 1 template/image. Do a multi minima/maxima detection ## OLD CODE LEFT BUT DONT DO IT, NOT GOOD PREACTICE !! Normalise the correlation map to 0-1 (easier to apply the threshold) ## Rather use normalised method only for the computation of the correlation map (by default normalised method are 0-1 bound) # The normalised method are already normalised to 0-1 but it is more work to take it into account in this function # WARNING : this normalisation normalise regarding to the maxima of the given correlation map # Not good because it means the thresholding is define relative to a correlation map : a score of 1 might not correspond to a correlation of 1 # But only means that the pixel was the maximum of this particular correlation map #CorrMapNormCV = Mat() #normalize(CorrMapCV, CorrMapNormCV, 0, 1, NORM_MINMAX, CV_32FC1, None) # Visualisation for debugging #CorrMapNorm = MatToImProc(CorrMapNormCV) #CorrMapNorm = ImagePlus("Normalised", CorrMapNorm) #CorrMapNorm.show() ### Maxima/Minima detection on the correlation map ## Difference-based method : we look for min value. For that we detect maxima on an inverted correlation map if MinMax=="Min": # Invert the correlation map : min becomes maxima One = Scalar(1.0) CorrMapInvCV = subtract(One, CorrMapCV).asMat() #CorrMapInv = MatToImProc(CorrMapInvCV) #CorrMapInv = ImagePlus("Inverted", CorrMapInv) #CorrMapInv.show() # Apply a "TO ZERO" threshold on the correlation map : to compensate the fact that maxima finder does not have a threshold argument # TO ZERO : below the threshold set to 0, above left untouched # NB : 1-score_threshold since we have inverted the image : we want to look for minima of value <x so we have to look for maxima of value>1-x in the inverted image CorrMapThreshCV = Mat() threshold(CorrMapInvCV, CorrMapThreshCV, 1-Score_Threshold, 0, CV_THRESH_TOZERO) CorrMapThresh = MatToImProc(CorrMapThreshCV) # Keep this conversion, not only for visualisation #CorrMapThreshImp = ImagePlus("Thresholded", CorrMapThresh) #CorrMapThreshImp.show() ## Correlation-based method : we look for maxima elif MinMax=="Max": # Apply a "TO ZERO" threshold on the correlation map : to compensate the fact that maxima finder does not have a threshold argument # TO ZERO : below the threshold set to 0, above left untouched # NB : 1-score_threshold since we have inverted the image : we want to look for minima of value <x so we have to look for maxima of value>1-x in the inverted image CorrMapThreshCV = Mat() threshold(CorrMapCV, CorrMapThreshCV, Score_Threshold, 0, CV_THRESH_TOZERO) CorrMapThresh = MatToImProc(CorrMapThreshCV) # Keep this conversion, not only for visualisation #CorrMapThreshImp = ImagePlus("Thresholded", CorrMapThresh) #CorrMapThreshImp.show() ## For both cases (Multi-Min/Max-detection) detect maxima on the thresholded map # Detect local maxima excludeOnEdge = False # otherwise miss quite a lot of them Polygon = MaximumFinder().getMaxima(CorrMapThresh, Tolerance, excludeOnEdge) # Maxima as list of points #roi = PointRoi(Polygon) # Generate Hit from max coordinates #print Polygon.npoints," maxima detected in this score map" if Polygon.npoints!=0: # Check that there are some points indeed. Otherwise Polygon.xpoints and ypoints are anyway initialised with [0,0,0,0] even if Npoints=0 ! for i in range(Polygon.npoints): # dont directly loop on xpoints and ypoint since initialised with [0,0,0,0] ie less than 4 points we get some 0,0 coordinates # Get point coordinates X, Y = Polygon.xpoints[i], Polygon.ypoints[i] # Get Coeff Coeff = CorrMapThresh.getPixel(X, Y) Coeff = Float.intBitsToFloat(Coeff) # require java.lang.Float # Revert the score again if we were detecting minima initially (since found as maxima of a reverted correlation map) if MinMax=="Min": Coeff = 1-Coeff # Wrap into corresponding hit Extrema.append( (X, Y, Coeff) ) return Extrema