Skip to content

Instantly share code, notes, and snippets.

@pyropeter
Created August 19, 2012 20:53
Show Gist options
  • Save pyropeter/3397654 to your computer and use it in GitHub Desktop.
Save pyropeter/3397654 to your computer and use it in GitHub Desktop.
My try at QR code detection (unfinished & broken)
import math
import numpy
import cv2
def isPattern(one, two, three, four, five):
if not one:
return
size = float(one + two + three + four + five) / 7
one /= size
if one < 0.5 or 1.75 < one:
return
two /= size
if two < 0.5 or 1.75 < two:
return
three /= size * 3
if three < 0.5 or 1.75 < three:
return
four /= size
if four < 0.5 or 1.75 < four:
return
five /= size
if five < 0.5 or 1.75 < five:
return
return size
def findPatternsInRow(y, row):
width = row.shape[0]
candidates = []
one = two = three = four = five = 0
state = False
for i in range(width):
if row[i]:
if state:
five += 1
else:
five = 1
state = True
else:
if not state:
four += 1
else:
size = isPattern(one, two, three, four, five)
if size:
candidates.append((i, y, size))
one = three
two = four
three = five
four = 1
state = False
return candidates
def findPatterns(img):
height, width = img.shape
candidates = []
for i in range(0, height, 2):
candidates.extend(findPatternsInRow(i, img[i]))
candidates = [(int(round(x-3.5*r)),y,r) for x,y,r in candidates]
groups = []
for x,y,r in candidates:
for matches in groups:
x2, y2, r2 = matches[-1]
if math.sqrt((x-x2)**2 + (y-y2)**2) <= r*r2:
matches.append((x,y,r))
break
else:
groups.append([(x,y,r)])
patterns = []
for matches in groups:
count = float(len(matches))
if count <= 1:
continue
patterns.append((
sum([x for x,y,r in matches]) / count,
sum([y for x,y,r in matches]) / count,
sum([r for x,y,r in matches]) / count))
return patterns
def handlePattern(edges, img, x, y, r, rgbimg):
x1 = int(round(x - 4.5 * r))
x2 = int(round(x + 4.5 * r))
y1 = int(round(y - 4.5 * r))
y2 = int(round(y + 4.5 * r))
cv2.rectangle(rgbimg, (x1,y1), (x2,y2), (255,0,0), 1)
subimg = edges[y1:y2, x1:x2]
try:
lines = cv2.HoughLinesP(subimg, 0.5, math.pi/12, 10)
except cv2.error:
return
if lines == None:
cv2.line(rgbimg, (x1,y1), (x2,y2), (0,255,0), 1)
return
for lx1,ly1,lx2,ly2 in lines[0]:
cv2.line(rgbimg, (x1+lx1, y1+ly1),
(x1+lx2, y1+ly2), (0, 0, 255), 1)
v = cv2.VideoCapture(0)
while True:
res, rgbimg = v.read()
if not res:
break
img = cv2.cvtColor(rgbimg, cv2.COLOR_RGB2GRAY)
# img = cv2.medianBlur(img, 3)
# blur = cv2.GaussianBlur(img, (3, 3), 1.5)
# img = (img - blur) + 127
img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY_INV, 15, 5)
patterns = findPatterns(img)
edges = cv2.filter2D(img, 0, numpy.array((
(-1,-1,-1),(-1,8,-1),(-1,-1,-1)
), dtype=numpy.float))
for x,y,r in patterns:
handlePattern(edges, img,x,y,r, rgbimg)
# cv2.circle(rgbimg, (int(round(x)),int(round(y))),
# int(round(r*3.5)), (0,0,255), 1)
cv2.imshow("debug", rgbimg)
# img = cv2.filter2D(img, 0, numpy.array((
# (-1,-1,-1),(-1,8,-1),(-1,-1,-1)
# ), dtype=numpy.float))
# cv2.imshow("debug", img)
if cv2.waitKey(1) >= 0:
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment