class DM: def __init__(self, max_count, timeout): self.max_count = max_count self.timeout = timeout self.loadReader() self.symbols = [] #a symbol is a list of the content and four (x,y) points as a sub list return def loadReader(self): self.read = DataMatrix(max_count = self.max_count, timeout = self.timeout, shape = DataMatrix.DmtxSymbol10x10) return def scan(self, img): self.read.decode(size(img, 1), size(img, 0), buffer(img.tostring())) self.symbols = [] for idx in range(1, self.read.count()+1): self.symbols.append(self.read.stats(idx)) def setTimeout(self, v): self.timeout = v self.loadReader() return def setMaxCount(self, v): self.max_count = v self.loadReader() return def writeDM(self): # Write a Data Matrix barcode dm_write = DataMatrix() dm_write.encode("Hello, world!") dm_write.save("hello.png", "png") return
def handleargc(): for filename in sys.argv[1:]: if filename.endswith('.bin'): decodedm(str1=open(filename, 'rb').read()) else: from pydmtx import DataMatrix from PIL import Image dm_read = DataMatrix() img = Image.open(sys.argv[1]) dm_read.decode(img.size[0], img.size[1], buffer(img.tostring())) #print dm_read.count() #print dm_read.stats(1) decodedm(dm_read.message(1))
def decode(imgcv2): code = "" try: st = datetime.datetime.now() img = Image.fromarray(imgcv2) if img.mode != 'RGB': img = img.convert('RGB') dm_read = DataMatrix() code = dm_read.decode( img.size[0], img.size[1], buffer( img.tostring()), timeout=80, maxcount=1, corrections=3) end = datetime.datetime.now() if dm_read.count() == 1: # print code, end - st time = end - st print dm_read.stats(1), "t:", str(time)[6:] points = dm_read.stats(1)[1] # print "points:", points # os.system("beep -f1296 -l10") except Exception: print "error decode" pass return code, points
def __call__(self, img): d = DataMatrix(timeout=self.timeout_ms, max_count=self.max_count) # PIL RGB image from BGR np.ndarray # http://stackoverflow.com/a/4661652/1773758 img = Image.fromarray(np.roll(img, 1, axis=-1)) img = img.convert('RGB') res = d.decode(img.size[0], img.size[1], buffer(img.tostring())) res = [None] * d.count() for i in xrange(0, d.count()): res[i] = Barcode('Data Matrix', d.message(1+i)) return res
def parse_folder(folder, output_folder): # create output folder if it does not exist if not os.path.exists(output_folder): os.makedirs(output_folder) # check images in folder for fn in os.listdir(folder): if fn.lower().endswith(".jpg") and not fn.lower().startswith("crop_"): print "Working on %s" % fn fnpath = os.path.join(folder, fn) # Read a Data Matrix barcode dm = DataMatrix() img = Image.open(fnpath) # Get datetime from image exif data exif = get_exif(img) datetime = exif["DateTime"].split(" ")[0].replace(":", "") if DEBUG: print "Image date: %s" % datetime # only check bottom third column cell and sixth row w, h = img.size x_start = 3 * (w / 4) y_start = 3 * (h / 4) crop = img.crop((x_start, y_start, w, h)) if DEBUG: #write crop for debugging purposes crop.save(os.path.join(folder, "crop_" + fn)) # Detect identifier = dm.decode(crop.size[0], crop.size[1], buffer(crop.tobytes())) if identifier: print "Decoded shelf: %s" % identifier #move and rename image os.rename( fnpath, os.path.join(output_folder, identifier + "_" + datetime + ".jpg")) else: print "No value"
def parse_folder(folder, output_folder): # create output folder if it does not exist if not os.path.exists(output_folder): os.makedirs(output_folder) # check images in folder for fn in os.listdir(folder): if fn.lower().endswith(".jpg") and not fn.lower().startswith("crop_"): print "Working on %s" % fn fnpath = os.path.join(folder, fn) # Read a Data Matrix barcode dm = DataMatrix() img = Image.open(fnpath) # Get datetime from image exif data exif = get_exif(img) datetime = exif["DateTime"].split(" ")[0].replace(":","") if DEBUG: print "Image date: %s" % datetime # only check bottom third column cell and sixth row w, h = img.size x_start = 3*(w/4) y_start = 3*(h/4) crop = img.crop((x_start, y_start, w, h)) if DEBUG: #write crop for debugging purposes crop.save(os.path.join(folder, "crop_" + fn)) # Detect identifier = dm.decode(crop.size[0], crop.size[1], buffer(crop.tobytes())) if identifier: print "Decoded shelf: %s" % identifier #move and rename image os.rename(fnpath, os.path.join(output_folder, identifier + "_" + datetime + ".jpg")) else: print "No value"
from pydmtx import DataMatrix from PIL import Image # Write a Data Matrix barcode dm_write = DataMatrix() dm_write.encode("Hello, world!") dm_write.save("hello.png", "png") # Read a Data Matrix barcode dm_read = DataMatrix() img = Image.open("hello.png") print dm_read.decode(img.size[0], img.size[1], buffer(img.tostring())) print dm_read.count() print dm_read.message(1) print dm_read.stats(1)
class DmtxFinder: def __init__(self): self.cache = {} self.dm = DataMatrix() def Cached(self, name, rows, cols, type): key = (name, rows, cols) if not key in self.cache: self.cache[key] = cv.CreateMat(rows, cols, type) return self.cache[key] def find0(self, img): started = time.time() self.dm.decode( img.width, img.height, buffer(img.tostring()), max_count=4, #min_edge = 6, #max_edge = 19 # Units of 2 pixels ) print "brute", time.time() - started found = {} for i in range(self.dm.count()): stats = dm_read.stats(i + 1) print stats found[stats[0]] = stats[1] return found def find(self, img): started = time.time() gray = self.Cached('gray', img.height, img.width, cv.CV_8UC1) cv.CvtColor(img, gray, cv.CV_BGR2GRAY) sobel = self.Cached('sobel', img.height, img.width, cv.CV_16SC1) sobely = self.Cached('sobely', img.height, img.width, cv.CV_16SC1) cv.Sobel(gray, sobel, 1, 0) cv.Sobel(gray, sobely, 0, 1) cv.Add(sobel, sobely, sobel) sobel8 = self.Cached('sobel8', sobel.height, sobel.width, cv.CV_8UC1) absnorm8(sobel, sobel8) cv.Threshold(sobel8, sobel8, 128.0, 255.0, cv.CV_THRESH_BINARY) sobel_integral = self.Cached('sobel_integral', img.height + 1, img.width + 1, cv.CV_32SC1) cv.Integral(sobel8, sobel_integral) d = 16 _x1y1 = cv.GetSubRect( sobel_integral, (0, 0, sobel_integral.cols - d, sobel_integral.rows - d)) _x1y2 = cv.GetSubRect( sobel_integral, (0, d, sobel_integral.cols - d, sobel_integral.rows - d)) _x2y1 = cv.GetSubRect( sobel_integral, (d, 0, sobel_integral.cols - d, sobel_integral.rows - d)) _x2y2 = cv.GetSubRect( sobel_integral, (d, d, sobel_integral.cols - d, sobel_integral.rows - d)) summation = cv.CloneMat(_x2y2) cv.Sub(summation, _x1y2, summation) cv.Sub(summation, _x2y1, summation) cv.Add(summation, _x1y1, summation) sum8 = self.Cached('sum8', summation.height, summation.width, cv.CV_8UC1) absnorm8(summation, sum8) cv.Threshold(sum8, sum8, 32.0, 255.0, cv.CV_THRESH_BINARY) cv.ShowImage("sum8", sum8) seq = cv.FindContours(sum8, cv.CreateMemStorage(), cv.CV_RETR_EXTERNAL) subimg = cv.GetSubRect(img, (d / 2, d / 2, sum8.cols, sum8.rows)) t_cull = time.time() - started seqs = [] while seq: seqs.append(seq) seq = seq.h_next() started = time.time() found = {} print 'seqs', len(seqs) for seq in seqs: area = cv.ContourArea(seq) if area > 1000: rect = cv.BoundingRect(seq) edge = int((14 / 14.) * math.sqrt(area) / 2 + 0.5) candidate = cv.GetSubRect(subimg, rect) sym = self.dm.decode( candidate.width, candidate.height, buffer(candidate.tostring()), max_count=1, #min_edge = 6, #max_edge = int(edge) # Units of 2 pixels ) if sym: onscreen = [(d / 2 + rect[0] + x, d / 2 + rect[1] + y) for (x, y) in self.dm.stats(1)[1]] found[sym] = onscreen else: print "FAILED" t_brute = time.time() - started print "cull took", t_cull, "brute", t_brute return found
class Template(AdPythonPlugin): def __init__(self): # The default logging level is INFO. # Comment this line to set debug logging off self.log.setLevel(logging.DEBUG) # Make some generic parameters # You can change the Name fields on the EDM screen here # Hide them by making their name -1 params = dict(int1 = 101, int1Name = "Threshold block size", int2 = 13, int2Name = "Threshold C", int3 = 3, int3Name = "Kernel size", double1 = 0.35, double1Name = "Angle cos", double2 = 6.0, double2Name = "Curve epsilon", double3 = 15.0, double3Name = "Length diff") self.dm=DataMatrix() AdPythonPlugin.__init__(self, params) def paramChanged(self): # one of our input parameters has changed # just log it for now, do nothing. self.log.debug("Parameter has been changed %s", self) def processArray(self, arr, attr={}): # Turn the picture gray gray = cv2.cvtColor(arr, cv2.COLOR_RGB2GRAY) # copy the array output out = arr.copy() # Do an adaptive threshold to get a black and white image which factors in lighting thresh = cv2.adaptiveThreshold(gray, 255.0, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, self["int1"], self["int2"]) # Morphological filter to get rid of noise element = cv2.getStructuringElement(cv2.MORPH_RECT, (self["int3"], self["int3"])) morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, element, iterations=1) m = morph.copy() # Find squares in the image contours, hierarchy = cv2.findContours(morph, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) squares = [] for rawcnt in contours: cnt = cv2.approxPolyDP(rawcnt, self["double2"], True) cnt = cnt.reshape(-1, 2) l = len(cnt) if l < 4: continue # find distances between successive points dists = [(dist_between(cnt[i], cnt[(i+1)%l]),i) for i in xrange(l)] dists.sort(reverse=True) # if longest 2 line lengths are about the same and segments are # next to each other (d0, i0), (d1, i1) = dists[0], dists[1] if abs(d0 - d1) < self["double3"] and abs(i0 - i1) in (1, l-1) and \ d0 > self["int1"] and d1 > self["int1"]: # Find out which point is first in contour if i0 < i1 or (i1 == 0 and i0 == l-1): first = i0 else: first = i1 # Get cos of the angle of the corner pts = [cnt[first], cnt[(first+1)%l], cnt[(first+2)%l]] ac = angle_cos(*pts) if abs(ac) < self["double1"]: # work out the rotation of the lines angle0 = numpy.degrees(numpy.arctan((pts[0][0] - pts[1][0])/float(pts[1][1]-pts[0][1]))) angle2 = numpy.degrees(numpy.arctan((pts[2][0] - pts[1][0])/float(pts[1][1]-pts[2][1]))) # rotate vector by 90 degrees clockwise to get last point dx, dy = pts[1][0] - pts[0][0], pts[1][1] - pts[0][1] p3 = [pts[0][0] - dy, pts[0][1] + dx] pts.append(p3) pts = numpy.array(pts, 'int32') # now work out the bounding rectangle of those points x, y, w, h = cv2.boundingRect(pts.reshape((-1, 1, 2))) # and take a roi of it pad = self["int1"] / 10 threshroi = thresh[y-pad:y+h+pad, x-pad:x+w+pad] # work out the rotated bounding rectangle center, size, angle = cv2.minAreaRect(pts-(x-pad, y-pad)) if angle0 > angle2: if pts[1][1]-pts[0][1] < 0: angle += 180 else: if pts[1][1]-pts[0][1] < 0: angle += 90 else: angle += 270 # get the rotation matrix M = cv2.getRotationMatrix2D(center, angle, 1.0); # perform affine transform l = max(*threshroi.shape) rot = cv2.warpAffine(threshroi, M, (l, l)); # now decode it sym = self.dm.decode(l, l, buffer(rot.tostring()), max_count = 1) print sym if sym: cv2.putText(out, sym, (int(center[0]+x+pad), int(center[1]+y+pad)), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,0), 3) squares.append(pts) # Draw squares on the image cv2.drawContours(out, squares, -1, (255,0,0), 3) # Mask out the area of these polys #cv2.imwrite("/scratch/U/datamatrix_results.jpg", cv2.cvtColor(out, cv2.COLOR_RGB2BGR) ) return out
dmtx_image.paste(dmtx_im,bbox) # dmtx_im.save("/tmp/t1.png") # dmtx_image.save("/tmp/t2.png") # import pdb;pdb.set_trace() (width, height) = dmtx_image.size if findcode.low_res: dm_read = DataMatrix(max_count = 1, timeout = 300, min_edge = 20, max_edge = 32, threshold = 5, deviation = 10) else: dm_read = DataMatrix(max_count = 1, timeout = 300, min_edge = 20, max_edge = 32, threshold = 5, deviation = 10, shrink = 2) #dm_read = DataMatrix(max_count = 1, timeout = 300, min_edge = 20, max_edge = 32, threshold = 5, deviation = 10, shrink = SHRINK) #dm_read = DataMatrix(max_count = 1, timeout = 300, shape = DataMatrix.DmtxSymbol12x12, min_edge = 20, max_edge = 32, threshold = 5, deviation = 10) dmtx_code = dm_read.decode (width, height, buffer(dmtx_image.tostring())) if dmtx_code is not None and len(dmtx_code) == EXPECTED_LEN: how = "Quick Search: "+str(name) is_found = True else: dmtx_im.save("/tmp/t1.png") dmtx_image.save("/tmp/t2.png") #import pdb;pdb.set_trace() out = dmtx_code # if not is_found: # dm_read = DataMatrix(max_count = 1, timeout = 300, min_edge = 20, max_edge = 32, threshold = 5, deviation = 10)
class DmtxFinder: def __init__(self): self.cache = {} self.dm = DataMatrix() def Cached(self, name, rows, cols, type): key = (name, rows, cols) if not key in self.cache: self.cache[key] = cv.CreateMat(rows, cols, type) return self.cache[key] def find0(self, img): started = time.time() self.dm.decode(img.width, img.height, buffer(img.tostring()), max_count = 4, #min_edge = 6, #max_edge = 19 # Units of 2 pixels ) print "brute", time.time() - started found = {} for i in range(self.dm.count()): stats = dm_read.stats(i + 1) print stats found[stats[0]] = stats[1] return found def find(self, img): started = time.time() gray = self.Cached('gray', img.height, img.width, cv.CV_8UC1) cv.CvtColor(img, gray, cv.CV_BGR2GRAY) sobel = self.Cached('sobel', img.height, img.width, cv.CV_16SC1) sobely = self.Cached('sobely', img.height, img.width, cv.CV_16SC1) cv.Sobel(gray, sobel, 1, 0) cv.Sobel(gray, sobely, 0, 1) cv.Add(sobel, sobely, sobel) sobel8 = self.Cached('sobel8', sobel.height, sobel.width, cv.CV_8UC1) absnorm8(sobel, sobel8) cv.Threshold(sobel8, sobel8, 128.0, 255.0, cv.CV_THRESH_BINARY) sobel_integral = self.Cached('sobel_integral', img.height + 1, img.width + 1, cv.CV_32SC1) cv.Integral(sobel8, sobel_integral) d = 16 _x1y1 = cv.GetSubRect(sobel_integral, (0, 0, sobel_integral.cols - d, sobel_integral.rows - d)) _x1y2 = cv.GetSubRect(sobel_integral, (0, d, sobel_integral.cols - d, sobel_integral.rows - d)) _x2y1 = cv.GetSubRect(sobel_integral, (d, 0, sobel_integral.cols - d, sobel_integral.rows - d)) _x2y2 = cv.GetSubRect(sobel_integral, (d, d, sobel_integral.cols - d, sobel_integral.rows - d)) summation = cv.CloneMat(_x2y2) cv.Sub(summation, _x1y2, summation) cv.Sub(summation, _x2y1, summation) cv.Add(summation, _x1y1, summation) sum8 = self.Cached('sum8', summation.height, summation.width, cv.CV_8UC1) absnorm8(summation, sum8) cv.Threshold(sum8, sum8, 32.0, 255.0, cv.CV_THRESH_BINARY) cv.ShowImage("sum8", sum8) seq = cv.FindContours(sum8, cv.CreateMemStorage(), cv.CV_RETR_EXTERNAL) subimg = cv.GetSubRect(img, (d / 2, d / 2, sum8.cols, sum8.rows)) t_cull = time.time() - started seqs = [] while seq: seqs.append(seq) seq = seq.h_next() started = time.time() found = {} print 'seqs', len(seqs) for seq in seqs: area = cv.ContourArea(seq) if area > 1000: rect = cv.BoundingRect(seq) edge = int((14 / 14.) * math.sqrt(area) / 2 + 0.5) candidate = cv.GetSubRect(subimg, rect) sym = self.dm.decode(candidate.width, candidate.height, buffer(candidate.tostring()), max_count = 1, #min_edge = 6, #max_edge = int(edge) # Units of 2 pixels ) if sym: onscreen = [(d / 2 + rect[0] + x, d / 2 + rect[1] + y) for (x, y) in self.dm.stats(1)[1]] found[sym] = onscreen else: print "FAILED" t_brute = time.time() - started print "cull took", t_cull, "brute", t_brute return found
from M2Crypto import EC, EVP, BIO import binascii, sys, cryptimage from pydmtx import DataMatrix from PIL import Image debug=0 #read in the data from the image dm_read = DataMatrix(scheme=DataMatrix.DmtxSchemeBase256) img = Image.open("dm.png") data = dm_read.decode(img.size[0],img.size[1],img.tostring()) #extract public key and encrypted message ephpub, ciphertext = cryptimage.parse_input(data) ephemeral = EC.pub_key_from_der(cryptimage.build_asn1(ephpub)) if debug: sys.stderr.write("ct = %s\n" % binascii.b2a_hex(ciphertext)) ecpairpem = """-----BEGIN EC PRIVATE KEY----- MHcCAQEEIH8TNBOfV+JWVBr25KfjJ1007paZ/JnrvjxFzZThUgSToAoGCCqGSM49 AwEHoUQDQgAEtv1eCFuapm3ku1AdTt5eK1IVaAzH2MBQqreo3FBSE8EHxCsEGRvK auFV+AgDEQotZbdqzAojRoCjuhZcYP73Pg== -----END EC PRIVATE KEY----- """ #derive shared key ecbio = BIO.MemoryBuffer() ecbio.write(ecpairpem) ecpair = EC.load_key_bio(ecbio) ecder = ecpair.pub().get_der() ecpub = cryptimage.compress_key(cryptimage.strip_asn1(ecder))
def parseImages(self, files = None): if files != None: self.files = files n=0 m=0 failNum=0 lastCVTime = 0 timeForCV = 0 print "\nFiles to decode: ",len(self.files) stop = False # import pdb;pdb.set_trace() for filename in self.files: is_found = False # if filename.find('/') != -1: # self.myDir,filename = path.split(filename) # self.myDir += '/' lastCVTime = time() cv_orig,cv_smoo,cv_final = findcode.findAndOrient(self.myDir, filename, self.do_display, self.verbose) timeForCV += (time() - lastCVTime) cv.SaveImage(self.myDir+filename.replace('tif','jpg'),cv_final) test = cv.Avg(cv_final) if stop == True: pdb.set_trace() if test[0] < 130 and test[0] > 40: # hard threshold works for avision for img,name in [#[cv_smoo,"smooth"], #seems to introduce many errors [cv_final,"clipped"], [cv_orig,"original"]]: if is_found: break dmtx_im = Image.fromstring("L", cv.GetSize(img), img.tostring()) if name != "original": padding = 0.1 else: padding = 0 ncols,nrows = dmtx_im.size padw = (ncols)*padding padh = (nrows)*padding isize = (int(round(ncols+2*padw)),int(round(nrows+2*padh))) # Create a new color image onto which we can paste findcode output dmtx_image = Image.new('RGB',isize,0) bbox = (round(padw),round(padh),ncols+round(padw),nrows+round(padh)) dmtx_image.paste(dmtx_im,map(int,bbox)) (width, height) = dmtx_image.size # Send to datamatrix library if findcode.low_res: dm_read = DataMatrix(max_count = 1, timeout = 300, min_edge = 20, max_edge = 32, threshold = 5, deviation = 10) else: dm_read = DataMatrix(max_count = 1, timeout = 300, min_edge = 20, max_edge = 32, threshold = 5, deviation = 10, shrink = 2) #dm_read = DataMatrix(max_count = 1, timeout = 300, shape = DataMatrix.DmtxSymbol12x12, min_edge = 20, max_edge = 32, threshold = 5, deviation = 10) dmtx_code = dm_read.decode (width, height, buffer(dmtx_image.tostring())) if dmtx_code is not None and len(dmtx_code) == EXPECTED_LEN: how = "Quick Search: "+str(name) is_found = True out = dmtx_code if not is_found: self.failed.append(filename) else: failNum+=1 if is_found: n+=1 self.output[filename] = out #print filename, out, test[0] else: #print filename, None, test[0] pass #self.failed.append(filename) m+=1 print failNum, "failed to produce images worth decoding" print n,"of the",m-failNum,"remaining were successfully decoded." self.status += "\nFound %d of %d in "%(n,m) self.status += str(time()-self.totalTime)+" seconds.\n" self.status += "(OpenCV: "+str(timeForCV)+" sec)\n" if not(len(self.failed) == 0):# and verbose: dirr = ' '+self.myDir self.status+= "\nmissing: "+str(self.failed)+'\n' return self.output,self.failed,self.status
import os from pydmtx import DataMatrix from PIL import Image #------------------------------------------------------------ # write a data matrix barcode #------------------------------------------------------------ path = os.path.abspath('.') path = os.path.join(path, 'hello.png') matrix = DataMatrix() matrix.encode("Hello, world!") matrix.save(path, "png") #------------------------------------------------------------ # read a data matrix Barcode #------------------------------------------------------------ matrix = DataMatrix() image = Image.open(path) print matrix.decode(image.size[0], image.size[1], buffer(image.tostring())) print matrix.count() print matrix.message(1) print matrix.stats(1)
#!/usr/bin/python from PIL import Image from pydmtx import DataMatrix import sys import cv2.cv as cv #Decoding data OpenCV img = cv.LoadImage(sys.argv[1]) dm = DataMatrix() print dm.decode(img.width, img.height, img.tostring()) sys.exit(0) #Decoding data img = Image.open(sys.argv[1]) if img.mode != 'RGB': img = img.convert('RGB') dm = DataMatrix() print dm.decode(img.size[0], img.size[1], buffer(img.tostring())) ''' #Encode Data dm.encode("Hello World") dm.save("test.jpg","jpeg") '''
dm_read = DataMatrix(timeout=100, max_count=1, shape=1) while display.isNotDone(): if options.test: # re-read image image = Image("original.png") else: if calibrated: image_orig = cam.getImage() image = cam.undistort(image_orig) else: image = cam.getImage() overlay = DrawingLayer((image.width, image.height)) dm_read.decode(image.width, image.height, buffer(image.toString())) for count in range(dm_read.count()): stats = dm_read.stats(count + 1) # Highlight barcode arrow = [] arrow.append(stats[1][0]) arrow.append(stats[1][1]) arrow.append(stats[1][3]) arrow.append(stats[1][0]) arrow.append(stats[1][2]) overlay.lines(arrow, Color.RED, width=2) # Attempt to improve the co-ords of each corner best = []