How to find and read data matrix code using python

I am trying to read datamatrix barcodes on the bottom of microtubes. I tried libdmtx which has python bindings and works well enough when the matrix points are square, but much worse when they are round like here

datamatrix sample

Another complication is gloss, which in some cases reaches the area of ​​the code.

Barcodes are scanned in a rack on a flatbed scanner, so they are consistent in size and roughly centered. The orientation is random.

I came to the conclusion that I would need to find the codes and improve the image. I am using python and OpenCV 3.1. I've already tried threshold, outlines:

import matplotlib.pyplot as plt
import numpy as np
import cv2

well = plt.imread('/img/af59b9c68dbc59956e011f28e9879152.png')
well = cv2.cvtColor(well, cv2.COLOR_BGRA2GRAY)
plt.subplot(151); plt.imshow(well)

x, thr = cv2.threshold(well, .4[enter image description here][2], 1, cv2.THRESH_BINARY)
thr = np.uint8(thr)
plt.subplot(152); plt.imshow(thr)

dst, contours, hierarchy = cv2.findContours(thr.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
c = cv2.drawContours(np.zeros_like(thr), contours, -1, 255, 1)
plt.subplot(153); plt.imshow(c)

areas = map(lambda x: cv2.contourArea(cv2.convexHull(x)), contours)
max_i = areas.index(max(areas))
d = cv2.drawContours(np.zeros_like(thr), contours, max_i, 255, 1)
plt.subplot(154); plt.imshow(d)

rect = cv2.minAreaRect(contours[max_i])
box = cv2.boxPoints(rect)
box = np.int0(box)
e = cv2.drawContours(np.zeros_like(thr),[box],0,255,1)
plt.subplot(155); plt.imshow(e)

plt.show()

      

result

+3


source to share


1 answer


It turns out that the Harris corner detector (B) finds round elements with the correct settings very well.

result image here



After the threshold (C), we detect the contours of the resulting regions. Select the largest path (D) and find the smallest bounding rectangle (E).

import matplotlib.pyplot as plt
import numpy as np
import cv2

well = plt.imread('https://i.stack.imgur.com/kqHkw.png')
well = cv2.cvtColor(well, cv2.COLOR_BGRA2GRAY)
plt.subplot(151); plt.title('A')
plt.imshow(well)

harris = cv2.cornerHarris(well,4, 1,0.00)
plt.subplot(152); plt.title('B')
plt.imshow(harris)

x, thr = cv2.threshold(harris, 0.1 * harris.max(), 255, cv2.THRESH_BINARY)
thr = thr.astype('uint8')
plt.subplot(153); plt.title('C')
plt.imshow(thr)

dst, contours, hierarchy = cv2.findContours(thr.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
areas = map(lambda x: cv2.contourArea(cv2.convexHull(x)), contours)
max_i = areas.index(max(areas))
d = cv2.drawContours(np.zeros_like(thr), contours, max_i, 255, 1)
plt.subplot(154); plt.title('D')
plt.imshow(d)

rect =cv2.minAreaRect(contours[max_i])
box = cv2.boxPoints(rect)
box = np.int0(box)
e= cv2.drawContours(well,[box],0,1,1)
plt.subplot(155); plt.title('E')
plt.imshow(e)

plt.show()

      

+6


source







All Articles