def MatchTemplate(ImProc_Template, ImProc_Target, Method): ''' Function that performs the matching between one template (opencv matrix) and an image (ImagePlus) ImProc_Template : ImageProcessor object of the template image ImProc_Target : ImageProcessor object of the image in which we search the template Method : Integer for the template matching method (openCV) return the correlation map ''' # Convert to image matrix, 8-bit (if both are 8-bit) or 32-bit if ImProc_Template.getBitDepth()==8 and ImProc_Target.getBitDepth()==8: ImTemplateCV = ImProcToMat(ImProc_Template, Bit=8) ImTargetCV = ImProcToMat(ImProc_Target, Bit=8) else: ImTemplateCV = ImProcToMat(ImProc_Template, Bit=32) ImTargetCV = ImProcToMat(ImProc_Target, Bit=32) # Create a correlation map object and do the matching CorrMapCV = Mat() matchTemplate(ImTargetCV, ImTemplateCV, CorrMapCV, Method) # result directly stored in CorrMap return CorrMapCV
from org.bytedeco.javacpp.opencv_core import Mat, CvMat, vconcat ## Typical matrices ## # Identity Matrix of size (3x3) and type 8-bit Id = Mat().eye(3, 3, 0).asMat() print Id print CvMat(Id) # handy to visualise the matrix # Matrix of ones (3x3) One = Mat().ones(3, 3, 0).asMat() # Matrix of zeros (3x3) Zero = Mat().zeros(3, 3, 0).asMat() # Custom Matrices # 1D-Matrix can be initialize from a list # For 2D (or more) we have to concatenate 1D-Matrices Row1 = Mat([1, 2, 3, 4, 5]) # 1D matrix Row2 = Mat([6, 7, 8, 9, 10]) TwoColumn = Mat() # initialise output vconcat(Col1, Col2, TwoColumn) # output stored in TwoColumn print CvMat(TwoColumn)
CorrMapImp = ImagePlus("Score Map", CorrMap) 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()
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