关注公众号 `N学无止界` 获取更多
目录:
一、环境说明
二、背景
三、示例代码
四、思考总结
一、环境说明
本机环境:windows10 操作系统
使用工具:Visual Studio Code 1.74.3(user setup)
Python版本:Python --version
Python 3.9.16
pip版本: pip --version
pip 22.3.1 from C:\Users\Jack\.conda\envs\py\lib\site-packages\pip (python 3.9)
弱依赖条件:
本示例程序默认你已经阅读过 https://blog.csdn.net/Jack_software/article/details/129178322 文章,并获取到示例输出的内容
备注:
安装Python库命令: pip install [库名]=[版本号]
比如: pip install pyzbar==0.1.9
下载缓慢可以尝试利用下面命令更新国内镜像仓库
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip config set install.trusted-host https://pypi.tuna.tsinghua.edu.cn
二、背景
前情回顾 : 20230223-基于pyzbar识别条形码并标注示例-CSDN博客
该博文末尾说道 “针对识别不到或者图片质量差识别失败的条形码可以用OCR模式识别条形码”,过程中遇到最表重排问题。针对识别到的结果想按照一定的顺序显示,为了更好的接近人体看的顺序(这里以先上后下,先左后右)顺序给出输出结果。
在zbr给出的结果和OCR的结果合并后,导致原来的顺序(我遇到的图片有多个条形码需要识别)没有按照特定的顺序展示,因此,本次对结果进行重排。
三、示例代码
说明:本示例以 20230223-基于pyzbar识别条形码并标注示例-CSDN博客 的坐标,信息针对外接矩形找到 “左上角的点”
相关定义:
何为左上角的点:
ChatGPT定义:
程序代码:
# -*- coding: utf-8 -*-
# __ author:Jack
# date: 2023-02-23
def sort_points():
#Decoded(data=b'QR Code\xc3\x82\xc3\xab\xc3\x8a\xc3\x87\xc3\x93\xc3\x89\xc3\x88\xc3\x95\xc2\xb1\xc2\xbeDenso\xc2\xb9\xc2\xab\xc3\x8b\xc2\xbe\xc3\x93\xc3\x9a1994\xc3\x84\xc3\xaa9\xc3\x94\xc3\x82\xc3\x91\xc3\x90\xc3\x96\xc3\x86\xc2\xb5\xc3\x84\xc3\x92\xc2\xbb\xc3\x96\xc3\x96\xc2\xbe\xc3\x98\xc3\x95\xc3\xb3\xc2\xb6\xc3\xbe\xc3\x8e\xc2\xac\xc3\x82\xc3\xab\xc2\xb7\xc3\xbb\xc2\xba\xc3\x85\xc2\xa3\xc2\xac\xc3\x8b\xc3\xbc\xc2\xb3\xc3\xbd\xc2\xbe\xc3\x9f\xc3\x93\xc3\x90\xc3\x92\xc2\xbb\xc3\x8e\xc2\xac\xc3\x8c\xc3\xb5\xc3\x82\xc3\xab\xc2\xbc\xc2\xb0\xc3\x86\xc3\xa4\xc3\x8b\xc3\xbc\xc2\xb6\xc3\xbe\xc3\x8e\xc2\xac\xc3\x8c\xc3\xb5\xc3\x82\xc3\xab\xc3\x8b\xc3\xb9\xc2\xbe\xc3\x9f\xc3\x93\xc3\x90\xc2\xb5\xc3\x84\xc3\x90\xc3\x85\xc3\x8f\xc2\xa2\xc3\x88\xc3\x9d\xc3\x81\xc2\xbf\xc2\xb4\xc3\xb3\xc2\xa1\xc2\xa2\xc2\xbf\xc3\x89\xc2\xbf\xc2\xbf\xc3\x90\xc3\x94\xc2\xb8\xc3\x9f\xc2\xa1\xc2\xa2\xc2\xbf\xc3\x89\xc2\xb1\xc3\xad\xc3\x8a\xc2\xbe\xc2\xba\xc2\xba\xc3\x97\xc3\x96\xc2\xbc\xc2\xb0\xc3\x8d\xc2\xbc\xc3\x8f\xc3\xb3\xc2\xb6\xc3\xa0\xc3\x96\xc3\x96\xc3\x8e\xc3\x84\xc3\x97\xc3\x96\xc3\x90\xc3\x85\xc3\x8f\xc2\xa2\xc2\xa1\xc2\xa2\xc2\xb1\xc2\xa3\xc3\x83\xc3\x9c\xc2\xb7\xc3\x80\xc3\x8e\xc2\xb1\xc3\x90\xc3\x94\xc3\x87\xc2\xbf\xc2\xb5\xc3\x88\xc3\x93\xc3\x85\xc2\xb5\xc3\xa3\xc3\x8d\xc3\xa2\xc2\xa3\xc2\xac\xc2\xbb\xc2\xb9\xc2\xbe\xc3\x9f\xc3\x93\xc3\x90\xc3\x88\xc3\xa7\xc3\x8f\xc3\x82\xc3\x96\xc3\xb7\xc3\x92\xc2\xaa\xc3\x8c\xc3\x98\xc2\xb5\xc3\xa3\xc2\xa3\xc2\xba', type='QRCODE', rect=Rect(left=1374, top=511, width=162, height=163), polygon=[Point(x=1374, y=511), Point(x=1374, y=673), Point(x=1536, y=674), Point(x=1535, y=511)], quality=1, orientation='UP')
#Decoded(data=b'Aux(124)-TR', type='CODE128', rect=Rect(left=550, top=599, width=287, height=71), polygon=[Point(x=550, y=599), Point(x=550, y=669), Point(x=837, y=670), Point(x=837, y=600)], quality=72, orientation='UP')
#Decoded(data=b'A000800A', type='CODABAR', rect=Rect(left=53, top=551, width=292, height=104), polygon=[Point(x=53, y=551), Point(x=53, y=655), Point(x=345, y=652), Point(x=345, y=554)], quality=101, orientation='UP')Decoded(data=b'123ABC', type='CODE39', rect=Rect(left=61, top=418, width=294, height=45), polygon=[Point(x=61, y=419), Point(x=61, y=463), Point(x=355, y=458), Point(x=355, y=418)], quality=44, orientation='UP')
#Decoded(data=b'BJ100080', type='CODE93', rect=Rect(left=535, top=381, width=290, height=94), polygon=[Point(x=535, y=381), Point(x=535, y=475), Point(x=825, y=474), Point(x=825, y=382)], quality=95, orientation='UP')Decoded(data=b'69012341', type='EAN8', rect=Rect(left=169, top=227, width=201, height=90), polygon=[Point(x=169, y=227), Point(x=169, y=317), Point(x=265, y=317), Point(x=370, y=316), Point(x=370, y=228)], quality=144, orientation='UP')
#Decoded(data=b'0089000006007', type='EAN13', rect=Rect(left=681, top=207, width=147, height=83), polygon=[Point(x=681, y=207), Point(x=681, y=289), Point(x=828, y=290), Point(x=828, y=212)], quality=82, orientation='UP')
#Decoded(data=b'6901234567892', type='EAN13', rect=Rect(left=151, top=32, width=264, height=90), polygon=[Point(x=151, y=33), Point(x=151, y=121), Point(x=287, y=122), Point(x=415, y=122), Point(x=415, y=32)], quality=144, orientation='UP')
#Decoded(data=b'0089600124569', type='EAN13', rect=Rect(left=635, top=16, width=253, height=84), polygon=[Point(x=635, y=17), Point(x=635, y=99), Point(x=888, y=100), Point(x=888, y=16)], quality=132, orientation='UP')
#Decoded(data=b'1234567890', type='I25', rect=Rect(left=1051, top=0, width=292, height=101), polygon=[Point(x=1051, y=1), Point(x=1051, y=101), Point(x=1343, y=100), Point(x=1343, y=0)], quality=102, orientation='UP')
#Rect(left=1374, top=511, width=162, height=163), polygon=[Point(x=1374, y=511), Point(x=1374, y=673), Point(x=1536, y=674), Point(x=1535, y=511)]
#Rect(left=550, top=599, width=287, height=71), polygon=[Point(x=550, y=599), Point(x=550, y=669), Point(x=837, y=670), Point(x=837, y=600)]
#Rect(left=53, top=551, width=292, height=104), polygon=[Point(x=53, y=551), Point(x=53, y=655), Point(x=345, y=652), Point(x=345, y=554)]
#Rect(left=61, top=418, width=294, height=45), polygon=[Point(x=61, y=419), Point(x=61, y=463), Point(x=355, y=458), Point(x=355, y=418)]
#Rect(left=535, top=381, width=290, height=94), polygon=[Point(x=535, y=381), Point(x=535, y=475), Point(x=825, y=474), Point(x=825, y=382)]
#Rect(left=169, top=227, width=201, height=90), polygon=[Point(x=169, y=227), Point(x=169, y=317), Point(x=265, y=317), Point(x=370, y=316), Point(x=370, y=228)]
#Rect(left=681, top=207, width=147, height=83), polygon=[Point(x=681, y=207), Point(x=681, y=289), Point(x=828, y=290), Point(x=828, y=212)]
#Rect(left=151, top=32, width=264, height=90), polygon=[Point(x=151, y=33), Point(x=151, y=121), Point(x=287, y=122), Point(x=415, y=122), Point(x=415, y=32)]
#Rect(left=635, top=16, width=253, height=84), polygon=[Point(x=635, y=17), Point(x=635, y=99), Point(x=888, y=100), Point(x=888, y=16)]
#Rect(left=1051, top=0, width=292, height=101), polygon=[Point(x=1051, y=1), Point(x=1051, y=101), Point(x=1343, y=100), Point(x=1343, y=0)]
arr = [[[1374, 511], [1374, 673], [1536, 674], [1535, 511]],\
[[550, 599], [550, 669], [837, 670], [837, 600]],\
[[53, 551], [53, 655], [345, 652], [345, 554]], \
[[61, 419], [61, 463], [355, 458], [355, 418]], \
[[535, 381], [535, 475], [825, 474], [825, 382]], \
[[169, 227], [169, 317], [265, 317], [370, 316], [370, 228]],\
[[681, 207], [681, 289], [828, 290], [828, 212]], \
[[151, 33], [151, 121], [287, 122], [415, 122], \
[415, 32]], [[635, 17], [635, 99], [888, 100], \
[888, 16]], [[1051, 1], [1051, 101], [1343, 100], [1343, 0]]]
#--- 1374 511
#--- 550 599
#--- 53 551
#--- 61 418
#--- 535 381
#--- 169 227
#--- 681 207
#--- 151 32
#--- 635 16
#--- 1051 0
for i in arr:
p = getLeftTopPoint(i)
print('---',p)
#--- (1374, 511)
#--- (550, 599)
#--- (53, 551)
#--- (61, 419)
#--- (535, 381)
#--- (169, 227)
#--- (681, 207)
#--- (151, 33)
#--- (635, 17)
#--- (1051, 1)
'''
获取外接矩形左上角的点
'''
def getLeftTopPoint(points):
# 距离x轴最近的2个点
sort_1 = sorted(points,key=lambda x:(x[1],x[0]))[:2]
# 距离y轴最近的1个点
sort_2 = sorted(sort_1,key=lambda x:x[0])[0]
return tuple(sort_2)
#tuple(sorted(sorted(points,key=lambda x:(x[1],x[0]))[:2],key=lambda x:x[0])[0])
if __name__=='__main__':
sort_points()
四、思考总结
## 核心算法
'''
获取外接矩形左上角的点
'''
def getLeftTopPoint(points):
# 距离x轴最近的2个点
sort_1 = sorted(points,key=lambda x:(x[1],x[0]))[:2]
# 距离y轴最近的1个点
sort_2 = sorted(sort_1,key=lambda x:x[0])[0]
return tuple(sort_2)
#tuple(sorted(sorted(points,key=lambda x:(x[1],x[0]))[:2],key=lambda x:x[0])[0])
if __name__=='__main__':
sort_points()
上述算法按照逻辑思维按照y轴排序求的最小的两个点,紧接着在找到最小的x点,最后求得左上角的点。根据需要的场景满足业务需求,后续如果遇到对坐标进行进一步识别,比如 左上角,右上角,右下角,左下角 顺序进行重排,欢迎大家沟通。