python - How to make a for loop from left to right, top to bottom in Python?
问题描述
I am trying to make a QR Code, and be able to read the data that is on the code itself. I am able to write the information, as well as see the bit values for the QR Code. When I read the QR Code through the code I have written, it gives me a completely different set of bits than what was written.
Code for reading the QR Code:
i,j=150,150
step=37
charRep=""
for byte in range(150,450):
color=int(img[i,j])
# ~ print(color)
if (color==int(255)):
charRep+="0"
elif (color==int(0)):
charRep+="1"
i+=step
if i>=412:
i=150
j+=step
if j>=412:
break
show(img)
This QR Code, with my code, says "Test", in binary notation, with the first character being the top row, the second the one below, so on.
The way I have my code for writing onto the QR Code template is I take the bits and write them, left to right, top to bottom. However, my code doesn't read back the data from the QR Code in the same way. I am wondering what to change with my code to make it work properly.
Minimal Reproducible Example Code:
import numpy as np
import cv2
def show(img,wait=0,destroy=True):
img=np.uint8(img)
cv2.imshow("image",img)
cv2.waitKey(wait)
if destroy:
cv2.destroyAllWindows()
def straighten(img,data):
color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# ~ print(len(contours))
cv2.drawContours(color, contours, -1, (0,255,0), 3)
# ~ show(color)
targets=[]
while len(contours):
contour=contours.pop()
_,x,y=stats(contour)
friends=[]
for index,c in enumerate(contours):
_,i,j=stats(c)
if np.hypot(x-i,y-j)<5:
friends.append(index)
for index in friends[::-1]:
del contours[index]
targets.append((len(friends)+1,x,y))
targets.sort()
targets=targets[-4:]
points=np.float32([[500,500],[500,100],[100,100],[100,500]])
source=np.float32([[x,y] for c,x,y in targets])
M=cv2.getPerspectiveTransform(source,points)
dst=cv2.warpPerspective(img, M, (600,600))
_,img=cv2.threshold(dst,127,255,cv2.THRESH_BINARY)
i,j=150,150
step=37
charRep=""
for byte in range(150,450):
color=int(img[i,j])
# ~ print(color)
if (color==int(255)):
charRep+="0"
elif (color==int(0)):
charRep+="1"
i+=step
if i>=412:
i=150
j+=step
if j>=412:
break
print(charRep)
show(img)
def stats(contour):
M = cv2.moments(contour)
return M['m00'],(M['m10']/M['m00']),(M['m01']/M['m00'])
def data2bits(data):
bits=""
for i in range(len(data)):
binary=str(bin(ord(data[i])))
binary=binary.replace("0b","0")
binary=binary.zfill(8)
bits+=binary
# ~ print(bits)
bits=bits.ljust(64,'0')
print("\nThese are the bits of the data you put in:\n"+str(bits)+"\n")
return bits
def bits2pixels(bits,qrCode):
i,j=150,150
step=37
for bit in bits:
if (bit=="1"):
dim = 37
color=(0,0,0)
elif (bit=="0"):
i+=step
if i>=412:
i=150
j+=step
if j>=412:
break
continue
cv2.rectangle(qrCode,(i,j),(i+dim,j+dim),color,-1)
i+=step
if i>=412:
i=150
j+=step
if j>=412:
break
show(qrCode)
return(qrCode)
def bits2data(bits):
string_blocks = (bits[i:i+8] for i in range(0, len(bits), 8))
string = ''.join(chr(int(char, 2)) for char in string_blocks)
print("This is the data you typed in, converted from the bits:\n"+str(string))
qrCode=cv2.imread("scan.png",0)
data=input("Put in the data you want and you will get the binary output for the first 8 characters.\nIf the data put in is less than 8 characters long, the bits will be filled up\nbut will be removed when the data is recompiled.\nType in your data: ")
data=data[:8]
bits=data2bits(data)
qrCode=bits2pixels(bits,qrCode)
bits2data(bits)
straighten(qrCode,data)
解决方案
推荐阅读
- python - 在复杂的嵌套字典/列表中搜索键、值对
- python - 为什么softmax分类器梯度除以批量大小(CS231n)?
- java - 使用 Itext PDF 创建 PDF 文件时出现空白页
- java - 我们可以将背包问题转换为对数时间吗?
- yacc - byacc/j 和 jflex 中的错误恢复使用 yacc 中的错误标记
- python - 在python中使用另一个函数的结果
- flutter - Flutter:如何使用 setter 重置值
- java - 有没有办法解决':app:checkDebugDuplicateClasses'。在颤振?
- php - 找不到类“数据库\播种机\”的问题
- javafx - javafx 组合框复选框多选过滤