穿越火线辅助_openCV 进阶之三:鼠标选取ROI进行文档透视转换

(注:部分代码参考作者skyblue NG博客修改,部分代码不适用于新版本,因此已修改为在3.7中正常工作。)。

上一节介绍了如何自动找到边缘并获取文档轮廓来执行透视转换。图像文件比较明确时,这种转换仍然简单,但也存在先天缺陷。也就是说,实际应用得到的图像对获得文档轮廓不是很好。因此,必须通过手动鼠标选择需要转换的区域,找到解决此问题的其他方法。(大卫亚设,Northern Exposure(美国电视剧),这可以适用于大部分情况。

整个想法是这样的。

第一步:必须使用tkinter图形界面构建用于导入图像等操作的GUI

第二步:定义鼠标事件并选择导入图像的ROI区域。其中,用鼠标显示ROI四个角的坐标。

步骤3:调用上一节中使用的转换和扫描程序,将扫描程序修改为函数

步骤4:显示结果

好像不难。当然,我觉得你应该对tkinter有所了解。但是参考文档并不难理解这些代码。而且我做了很多注释,最大限度地减少了理解代码的困难。关键是必须自己亲自验证。

现在转到第一步:填写GUI表格

#-*-代码3360 utf-8-*-

From tkinter import *

需要from tkinter . file dialog import ask open filename #文件对话框

Import cv2

Import numpy as NP

From tkinter import ttk

Import win32clipboard as wcld

Import操作系统

From scan_module import wrapped

Root=Tk() #创建根表单

将Frm1=Frame(root) # frm1加载为根窗体

直到放置了Frm1.pack (side=’ top ‘,anchor=’ e ‘,ipadx=1,ipady=1) # frm1帧

将Frm2=Frame(root) #第二个帧加载到根表单中

Frm2.pack (side=’ top ‘,anchor=’ w ‘,ipadx=1,ipady=3)

root . title(“ROI裁剪”)

Label(frm1,text=’ROI裁剪初版’,fg=’gray ‘)。pack(side=’right’) #在第1帧加载标记

Ttk。Button(frm2,text=“打开文件”,command=myopen)。pack (side=’ left ‘,ipadx=8) #

Ttk。Label(frm2,text=’座标:’)。pack(side=’left ‘,ipadx=0) #在第2帧的左侧加载另一个标记

Msg=StringVar()

Ttk.entry (frm2,width=60,textvariable=msg)。紧接在pack (side=’ left ‘,ipadx=0) #之后

Ttk。Button(frm2,text=’ copy ‘,command=send _ to _ clibboard)。pack (side=’ right ‘)

#进入消息循环

Root.mainloop() # tkinter通常需要运行mainloop()方法才能创建窗口

是这样制作的。

第二步:定义“打开文件”按钮事件,myopen()函数

Filename=’ ‘

Def myopen():

全局文件名、img、ROI

通过# askopenfilename()方法直接获取文档名称

filename=ask open filename(filetype s=(‘ template files ‘,’ *)。’ t plate ‘),(‘ html files ‘,)*。htm),(“所有文件”,* .* ‘))

打印(文件名)

Img=cv2.imread(文件名)

ROI=img.copy()

# setMouseCallback()创建鼠标回调函数,每次用鼠标左键单击图像并再次提起时,该函数都会调用三次鼠标响应函数

#此处调用的回调函数是上面定义的on_mouse()函数,当鼠标激活打开的图像时执行相应的操作。

Cv2。命名窗口(“src”)

Cv2。setmousecallback (‘src ‘,on _ mouse)

CV2 . IMSHOW(‘SRC’,img)。

Cv2.waitKey(0)

Cv2.destroyAllWindows()

要定义On_mouse()函数,请执行以下操作:

# -鼠标操作相关-

LsPointsChoose=[] #选定点的坐标列表

TpPointsChoose=[]

PointsCount=0 #鼠标点击次数

Count=0

PointsMax=4 #初始化选定的点数

Defon _ mouse(事件,x,y,flags,param)3360

全球img、point1、point2、count、points max

Global lspointschoose,tppointschoose #保存选定的点

Global pointsCount #鼠标点击点数

全球img2、ROI _ bymouse _ flag

Img2=img.copy() #这一行代码每次都要重画,以确保不要画太多

if event==cv2 . event _ lbuttondown : #单击左键

PointsCount=pointsCount 1

print(‘ pointscount 3360 ‘,points count)

Point1=(x,y)

打印(x,y)

#绘制单击点

Cv2.circle (img2、point1、10、(0,255,0)、2)

#将选定的点保存到列表中

用于转换为LsPointsChoose.append([x,y]) # array以提取多边形ROI

用于绘制TpPointsChoose.append((x,y)) #点

# –

#用鼠标用直线连接选定的点

打印(len (tppointschoose))

for I inrange(len(tppointschoose)-1):

打印(“I”,I)。

Cv2.line (img2、tppointschoose [I]、tppointschoose [i1]、(0,0,255)、2)

单击# – pointMax可以提取图形-

IF(points count==points max)3360

# -绘制感兴趣的区域-

Cv2.line (img2、tppointschoose [0]、tppointschoose [pointsmax-1]、(0,0,255)、2)

调用ROI_byMouse() #绘图函数来绘制感兴趣的区域

ROI_bymouse_flag=1

I=0

PointsCount=0

TpPointsChoose=[]

LsPointsChoose=[]

CV2 . IMSHOW(‘SRC’,img2)。

# -右键单击轨迹-

if event==cv2 . event _ rbut tondown 3360 #右键单击

打印(“right-mouse”)

PointsCount=0

TpPointsChoose=[]

LsPointsChoose=[]

CV2 . IMSHOW(‘SRC’,img2)。

重新定义ROI_byMouse()函数

def ROI _ by mouse()3360

全球src、ROI、ROI _ flag、mask2、lspointschoose、msg

Mask=np.zeros (img.shape,np.uint8)

#print(lsPointsChoose)

Msg.set(lsPointsChoose)#将选定点坐标的列表存储在Msg变量中

#print(msg.get())

Pts=np.array ([lspointschoose],np.int32) # pts是多边形的顶点列表(顶点集)

pts=pts . re shape(-1、1、2))

#print(pts)

#其中reshape的第一个参数是-1。这表示这个维度的长度是根据下一个维度的计算来计算的。

# OpenCV,在绘制之前,需要将多边形的顶点坐标更改为顶点数12维的矩阵

# -绘制多边形-

# mask=cv2.polylines (mask,[pts],true,(255,255,255))

# -填满的多边形-

Mask2=cv2.fillpoly (mask,[pts],(255,255,255))

#cv2.imshow(‘mask ‘,mask2)

cv2 . im write(“mask . BMP”,mask2)

ROI=cv2.bitwise_and(mask2,img)

Wrap_img=wrapped(ROI)

cv2 . im write(“ROI . BMP”,ROI)

cv 2 . im show(“ROI”,ROI)

Cv2.imshow (‘wrap _ image ‘,wrap _ img)

此示例定义“复制到剪贴板”函数send_to_clibboard()以查看所选四个角的坐标。主要用于验证效果,但实际上可能不使用。但是你可以参考。

Def send_to_clibboard():

Wcld。OpenClipboard()

Wcld。EmptyClipboard()

Wcld.setclipboarddata (wcld .CF_UNICODETEXT,msg.get ()) #要正确解析,请在此处。请使用cf _ unicodetext方法

Wcld。CloseClipboard()

将前面的scan.py修改为scan_module()模块,以调用以下内容:

#导入所需的库

#获取上一节构建的模块和函数

from transform import four _ point _ transform

别忘了安装# scikit-image软件包。threshold-local函数可以帮助您处理黑白图像

from skimage . filters import threshold _ local

Import numpy as NP

Import argparse

Import cv2

#imutils是非常有用的图像处理库,如resize/cropping/rotate等图像基本编辑

Import imutils

#此module将直接返回转换后的图像以进行其他程序调用

def wrapped(image)3360

#第一阶段

#加载图像,计算新图像和新图像的高度比例,复制副本,修改大小。

#为了加快图像处理速度,使边缘检测阶段更加准确。

#已将扫描图像的高度调整为500像素。

#我们也特别注意跟踪图像的原始高度和新高度的比例。

#这样就可以扫描原始图像,而不是调整大小的图像。

# img=cv2.imread(图像)

Img=image

Ratio=img.shape[0]/500.0

Orig=img.copy()

Img=imutils.resize (img,height=500)

#将图像转换为灰度,应用模糊,然后找到边缘

Gray=cv2.cvtcolor (img,cv2.color _ bgr2gray)

Gray=cv2.gaussianblur (gray,(5,5),0)

Edged=cv2.canny(灰色,70,250)

#显示原始图像和检测到的边缘图像。不需要显示

# print(“step 13360边缘检测”)

#cv2.imshow(‘Image ‘,img)

#cv2.imshow(‘Edged ‘,Edged)

#cv2.waitKey(0)

#cv2.destroyAllWindows()

#第二阶段

#根据边缘图像,找到轮廓保持最大的东西,并在图像中识别

CNTs=cv2 . find contours(edged . copy(),cv2.retr _ list,cv2.chain _ approx _ simple)

CNTs=im utils . grab _ contours(CNTs)

Cnts=sorted (CNTs,key=cv2.contourarea,reverse=true)[33605]

#循环处理

For c in cnts:

#大致轮廓

Peri=cv2.arcLength(c,True)

Approx=cv2.approxpolydp (c,0.02 * peri,true)

#如果要查找的大致轮廓有四个角,假设我们需要查找

IF LEN(Approx)==43360

屏幕CNT=approx

布雷克

#显示文档的轮廓在此模块中不需要显示

# print(“step 23360 find contours of paper”)

# cv2.drawcontours (img,[screencnt],-1,(0,255,0),2)

# cv2 . imshow(“Outline”,img)

#cv2.waitKey(0)

#cv2.destroyAllWindows()

#第三阶段

应用# 4点变换生成鸟瞰

warped=four _ point _ transform(orig,screencnt.reshape (4,2) * ratio)

#将变形的图像转换为灰度

Warped=cv2.cvtcolor (warped,cv2.color _ bgr2gray)

T=threshold _ local (warped,11,offset=10,method=’ Gaussian ‘)

Warped=(warped t)。astype (‘uint8’) * 255

Return warped

此函数返回转换后的图像。

现在,让我们测试一下效果。

穿越火线辅助_openCV 进阶之三:鼠标选取ROI进行文档透视转换

观看视频,演示测试过程。

穿越火线辅助_openCV 进阶之三:鼠标选取ROI进行文档透视转换

效果很好快动手设计自己的文档扫描仪。下次尝试OCR、文本识别和输出。这比较有挑战性。

    • 2会员总数(位)
    • 4265资源总数(个)
    • 7本周发布(个)
    • 0 今日发布(个)
    • 1522稳定运行(天)

    365卡盟提供最优质的游戏辅助