def __call__(self, image): params = util.utf8convert(self.inspection.parameters) retVal = [] #we assume all of this is validated and correct templates = [] # get templates from GridFS quality = 500.00 minDist = 0.2 minMatch = 0.4 #this is a temporary hack if( not params.has_key('template') ): print "Bailing due to lack of template." return [] # required param else: templ=Image(params['template']) templates=[templ] if( params.has_key('quality') ): quality = params['quality'] if( params.has_key('minDist') ): minDist = params['minDist'] if( params.has_key('minMatch') ): minMatch = params['minMatch'] # we want to optionally supply a count value, if we don't get count # number of hits we iterate through the templates, try to match up the # overlapping ones, and then get a final count. for t in templates: fs = image.findKeypointMatch(t,quality,minDist,minMatch) if fs is not None: break if fs is not None: fs.draw() for f in fs: # do the conversion from SCV featureset to SimpleSeer featureset f._homography = None f._template = None f._avgColor = None #print f._minRect #print type(f._minRect) f.contour = [f._minRect[0],f._minRect[1],f._minRect[2],f._minRect[3]] ff = M.FrameFeature() ff.setFeature(f) retVal.append(ff) if( params.has_key("saveFile") ): image.save(params["saveFile"]) return retVal
def __call__(self, image): params = util.utf8convert(self.inspection.parameters) code = image.findBarcode() if not code: return [] if( params.has_key("saveFile") ): image.save(params["saveFile"]) return code
def __call__(self, image): params = util.utf8convert(self.inspection.parameters) # It is just going to be easier to mask over # all of the default params. canny = (50,100) #(cannyth1,cannyth2) threshold = 80 gap = 10 maxL = int(np.sqrt((image.width*image.width) + (image.height*image.height))) length = (30,maxL) # min / max angle = (None,None) retVal = [] #we assume all of this is validated and correct if( params.has_key('canny') ): canny = params['canny'] if( params.has_key('length') ): length = params['length'] if( params.has_key('gap') ): gap = params['gap'] if( params.has_key('angle') ): angle = params['angle'] if( params.has_key('threshold') ): angle = params['threshold'] fs = image.findLines(threshold,length[0],gap,canny[0],canny[1]) if fs is not None: if( angle[0] is not None and angle[1] is not None ): fs = FeatureSet(f for f in fs if( f.angle()>=angle[0] and f.angle()<=angle[1]) ) # filter on the angles if( length[1] is not None ): # we already know that we are greater than the min length fs = FeatureSet(f for f in fs if( f.length() <= length[1] ) ) fs.draw() for f in fs: # do the conversion from SCV featureset to SimpleSeer featureset f.lineLength= int(f.length()) ff = M.FrameFeature() ff.setFeature(f) retVal.append(ff) if( params.has_key("saveFile") ): image.save(params["saveFile"]) return retVal
def __call__(self, image): params = util.utf8convert(self.inspection.parameters) retVal = [] myWords = image.readText() #grrr ocr likes to spit back empty newlines if(len(myWords)==0 or myWords == " \n\n"): return [] if( params.has_key("saveFile") ): image.drawText(myWords,20,20,color=Color.RED) image.save(params["saveFile"]) return [OCRFeature(image,myWords)]
def sendMessage(self, o, data): if (len(data) > 0): msgdata = [dict( id = str(o.id), data = d[0:2], inspection_id = str(d[2]), frame_id = str(d[3]), measurement_id= str(d[4]), result_id= str(d[5]) ) for d in data] #log.info('pushing new data to ' + utf8convert(o.name) + ' _ ' + str(msgdata)) # Channel naming: OLAP/olap_name olapName = 'OLAP/' + utf8convert(o.name) + '/' ChannelManager().publish(olapName, dict(u='data', m=msgdata))
def __call__(self, image): pt0 = None pt1 = None canny1 = 0 canny2 = 100 width = 3 params = util.utf8convert(self.inspection.parameters) if( params.has_key("pt0")): pt0 = params["pt0"] else: # required return [] if( params.has_key("pt1")): pt1 = params["pt1"] else: # required return [] if( params.has_key("canny")): canny = params["canny"] canny1 = canny[0] canny2 = canny[1] if( params.has_key("width")): width = params["width"] result = image.edgeIntersections(pt0,pt1,width,canny1,canny2) retVal = [] if(result[0] is not None and result[1] is not None ): ff = M.FrameFeature() ewf = EdgeWidthFeature(image,[pt0,pt1],result) ff.setFeature(ewf) retVal.append(ff) if( params.has_key("saveFile") ): if(result[0] is not None and result[1] is not None ): image.drawCircle( result[0],10,color=Color.RED) image.drawCircle( result[1],10,color=Color.RED) image.drawLine( pt0, pt1,thickness=width,color=Color.GREEN) image.save(params["saveFile"]) return retVal
def __call__(self, image): params = util.utf8convert(self.inspection.parameters) retVal = [] #we assume all of this is validated and correct templates = [] # get templates from GridFS threshold = 3 method = "SQR_DIFF_NORM" #this is a temporary hack if( not params.has_key('template') ): print "Bailing due to lack of template" return [] # required param else: templ=Image(params['template']) templates=[templ] if( params.has_key('method') ): method = params['method'] if( params.has_key('threshold') ): threshold = params['threshold'] # we want to optionally supply a count value, if we don't get count # number of hits we iterate through the templates, try to match up the # overlapping ones, and then get a final count. for t in templates: fs = image.findTemplate(t,threshold,method) if fs is not None: break if fs is not None: fs.draw() for f in fs: # do the conversion from SCV featureset to SimpleSeer featureset ff = M.FrameFeature() f.image = None f.template = None ff.setFeature(f) retVal.append(ff) if( params.has_key("saveFile") ): image.save(params["saveFile"]) return retVal
def __call__(self, image): params = util.utf8convert(self.inspection.parameters) # It is just going to be easier to mask over # all of the default params. canny = 100 threshold = 350 distance = -1 radius = (None,None) retVal = [] #we assume all of this is validated and correct if( params.has_key('canny') ): canny = params['canny'] if( params.has_key('distance') ): distance = params['distance'] if( params.has_key('radius') ): radius = params['radius'] if( params.has_key('threshold') ): threshold = params['threshold'] fs = image.findCircle(canny,threshold,distance) if fs is not None: if( radius[0] is not None): fs = FeatureSet(f for f in fs if( f.radius()>=radius[0] ) ) if( radius[1] is not None ): fs = FeatureSet(f for f in fs if( f.radius()<=radius[1] ) ) fs.draw(width=3) for f in fs: # do the conversion from SCV featureset to SimpleSeer featureset ff = M.FrameFeature() ff.setFeature(f) retVal.append(ff) if( params.has_key("saveFile") ): image.save("derp.png") image.save(params["saveFile"]) return retVal
def __call__(self, image): params = util.utf8convert(self.inspection.parameters) code = image.findBarcode() if not code: return [] feats = [] for f in code: f.draw() ff = M.FrameFeature() code.image = image ff.setFeature(f) feats.append(ff) if( params.has_key("saveFile") ): image.save(params["saveFile"]) return feats
def test_convert_other(self): class MyObject(object): pass x = MyObject() encoded = util.utf8convert(x) assert encoded is x
def test_convert_list(self): encoded = util.utf8convert([u'foo\u0200', 'bar']) self.assertEqual(encoded, ['foo\xc8\x80', 'bar'])
def test_convert_dict(self): encoded = util.utf8convert({u'foo\u0200':'foo', 'bar': u'foo\u0200'}) self.assertEqual(encoded, { 'foo\xc8\x80':'foo', 'bar': 'foo\xc8\x80'})
def test_convert_unicode(self): encoded = util.utf8convert(u'foo\u0200') assert isinstance(encoded, str) unicode(encoded, 'utf-8') # verify valid utf-8 self.assertEqual(encoded, 'foo\xc8\x80')
def test_convert_str(self): encoded = util.utf8convert('foo') assert isinstance(encoded, str) unicode(encoded, 'utf-8') # verify valid utf-8 self.assertEqual(encoded, 'foo')
def __call__(self, image): params = util.utf8convert(self.inspection.parameters) #params = self.inspection.parameters # okay I am going to gut this, so it will break stuff. # the new method allows the user to use one of the following methods # # Hue - find things with a certain color # Color - find things with a certain color # Raw - binary adaptive or blanket threshold - old school blobs # FloodFill - pick a pixel and a tolerance - find blob from there # # eventually all of the location based approaches should support multiple locations # to sample from # # For hue and a raw the user needs to specify a single upper # and lower bound variable. # # For color and flood fill the user can specify both the # upper and lower color bound as two precise triplets # or as a single triplet as the delta around the color # The suggested UI for this # is a color palette in gimp where the user can select a region # around the value ... N.B. eventually we should actually render # this stuff in 3D and let people pare down the color cube/cone # # The user also has the option to invert the results, and # set the minimum and max size of the blob. # # If the user provides parameters for multiple of # the above approaches we return None. invert = False hue = None hueLocation = None doHue = False color = None colorLocation = None doColor = False location = None doFF = False thresh1 = None thresh2 = None # KAT NEED MINSIZE / MAXSIZE parse_error = False if params.has_key("invert"): invert = params["invert"] del params["invert"] #do the parsing for hue distance if( params.has_key("hueLocation")): # I am assuming this is the (x,y) pos of a reference pixel hueLoc = tuple(params['hueLocation']) del params["hueLocation"] hue = image[hueLoc[0],hueLoc[1]] hsv = Color.hsv(hue) hue = hsv[0] doHue = True elif( params.has_key("hue")): hue = int(params['hue']) del params["hue"] doHue = True if( params.has_key("colorLocation")): # I am assuming this is the (x,y) pos of a reference pixel colorLoc = tuple(params['colorLocation']) color = image[colorLoc[0],colorLoc[1]] del params["colorLocation"] doColor = True elif( params.has_key("color")): color = tuple(params['color']) del params["color"] doColor = True if( params.has_key("location")): # I am assuming this is the (x,y) pos of a reference pixel location = tuple(params['location']) del params["location"] doFF = True #These are for fine grain control of flood fill #We can also use them to pick out colors using the createBinaryMask function. if( params.has_key("thresh1") ): thresh1 = params['thresh1'] del params["thresh1"] if( params.has_key("thresh2") ): thresh1 = tuple(params['thresh2']) del params["thresh2"] #now get the other params thresh=-1 blocksize=0 p=5 minsize = 10 maxsize = 0 if params.has_key("thresh"): thresh = params["thresh"] del params["thresh"] if params.has_key("blocksize"): blocksize = params["blocksize"] del params["blocksize"] if params.has_key("p"): p = params["p"] del params["p"] if params.has_key("minSize"): minsize = params["minSize"] del params["minSize"] if params.has_key("maxSize"): p = params["maxSize"] del params["maxSize"] count = 0 if( doFF ): count = count + 1 if( thresh1 is None ): count = count + 1 if( doHue ): count = count + 1 if( doColor ): count = count + 1 if( count > 1 ): # user gets to specify one operation - if they select two error out return [] if( doHue ):#hue distance mask = image.hueDistance(hue) mask = mask.binarize(thresh=thresh,blocksize=blocksize,p=p) # there is a lot more room to do cool stuff in here elif( doColor ): #color distance mask = image.colorDistance(color) mask = mask.binarize(thresh=thresh,blocksize=blocksize,p=p) # there is a lot more room to do cool stuff in here elif( doFF ): #eventually we could pepper an ROI with spots to get more robust results. if( thresh2 is not None): mask = image.floodFillToMask(location,lower=thresh1,upper=thresh2) else: mask = image.floodFillToMask(location,tolerance=thresh1) else: #vanilla binarize mask = image.binarize(thresh=thresh,maxv=255,blocksize=blocksize,p=p) # SUGGEST ALSO USING CREATE BINARY MASK HERE # WE COULD ALSO AUTOGEN MASK USING THE FIND BLOBS FROM PALLETTE IF YOU WANT TO GET FANCY if( invert ): mask = mask.invert() # SUGGEST ADDING AN OPTIONAL DILATE / ERODE HERE blobs = image.findBlobsFromMask(mask,minsize=minsize,maxsize=maxsize) if not blobs: return [] if params.has_key("top"): top = params["top"] if(top < len(blobs) ): blobs = blobs[(-1*top):] feats = [] for b in reversed(blobs): #change sort order to big->small c = b.meanColor() b.mColor = (int(c[0]),int(c[1]),int(c[2])) ff = M.FrameFeature() b.image = image ff.setFeature(b) feats.append(ff) if( params.has_key("saveFile") ): image.save(params["saveFile"]) return feats
def __call__(self, image): params = util.utf8convert(self.inspection.parameters) retVal = [] mask = Image((image.width,image.height)) if( params.has_key('w') and params.has_key('h') and params.has_key('x') and params.has_key('y') ): #rectangle if( params['x'] + params['w'] < image.width and params['y'] + params['h'] < image.height and params['y'] >= 0 and params['x'] >= 0 ): mask.drawRectangle(params['x'],params['y'],params['w'],params['h'],width=-1,color=Color.WHITE) mask = mask.applyLayers() fs = image.findBlobsFromMask(mask) ff = M.FrameFeature() if( fs is not None and len(fs) > 0 ): #fs[-1].draw() b = fs[-1] b.__class__ = BlobRegion c = b.meanColor() b.mColor = (int(c[0]),int(c[1]),int(c[2])) ff.setFeature(b) # a little hacky but I am sure that it works retVal = [ff] elif( params.has_key('x') and params.has_key('y') and params.has_key('r') ): # circle if( params['x'] + params['r'] < image.width and params['y'] + params['r'] < image.height and params['x'] - params['r'] >= 0 and params['y'] - params['r'] >= 0 ): r = params['r'] x = params['x'] y = params['y'] mask.drawCircle((x,y),r,thickness=-1,color=Color.WHITE) mask = mask.applyLayers() fs = image.findBlobsFromMask(mask) ff = M.FrameFeature() if( fs is not None and len(fs) > 0 ): #fs[-1].draw() b = fs[-1] b.__class__ = BlobRegion c = b.meanColor() b.mColor = (int(c[0]),int(c[1]),int(c[2])) ff.setFeature(b) retVal = [ff] elif( params.has_key('contour') ): contour = params['contour'] # this may bail out if( len(contour) >= 3 ): mask.dl().polygon(contour,filled=True,color=Color.WHITE) mask = mask.applyLayers() fs = image.findBlobsFromMask(mask) ff = M.FrameFeature() if( fs is not None and len(fs) > 0 ): #fs[-1].draw() b = fs[-1] b.__class__ = BlobRegion c = b.meanColor() b.mColor = (int(c[0]),int(c[1]),int(c[2])) ff.setFeature(b) retVal = [ff] if( params.has_key("saveFile") ): image.save(params["saveFile"]) return retVal