Python图片处理之图片裁剪的示例分析

小编给大家分享一下Python图片处理之图片裁剪的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

一、操作流程

首先会吧?

1.有张照片

这是网上随便找的一张照片,自行保存测试

2.看看照片

运行代码,其中show_img函数是展示照片

3.选择角点

按照左上,右上,右下,左下的顺序选择四个角点

如果担心自己选不好,可以直接去除我代码里的points的注释,那是我自己用的原版

4.最终结果

二、代码分析

import 没什么好说的

#如果python没有安装cv2,那么就安装python-opencv就好
importcv2ascv
importnumpyasnp

获取图片的长宽

#输入cv.imread后的图片,通过点击四个点选择要裁剪的部分
defget_window_size(src,bound=600):
h,w=src.shape[0],src.shape[1]
ifh>w:
h,w=bound,int(w*bound/h)
else:
h,w=int(h*bound/w),bound
return(h,w)

通过鼠标获取图片的坐标点,顺序是左上,右上,右下,左下

classIndexer:
def__init__(self,bound=4):
self.id=0
self.bound=bound

defget_id(self):
self.id=(self.id+1)
return(self.id)


defon_EVENT_LBUTTONDOWN(event,x,y,flags,param):
ifevent==cv.EVENT_LBUTTONDOWN:
img=param['src']
win_name=param['window']
indexer=param['indexer']
points=param['points']

curr_id=indexer.get_id()
points.append((x,y))
print('第{}个顶点:({},{})'.format(curr_id,x,y))

cv.circle(img,(x,y),10,(0,0,255),thickness=2)
cv.putText(
img,
str(curr_id),#文字
(x,y),#坐标
cv.FONT_HERSHEY_PLAIN,
5,#字号
(0,0,255),#字体颜色
thickness=2#粗细
)

cv.imshow(win_name,img)

#输入cv.imread后的图片,通过点击四个点选择要裁剪的部分
defget_points(src):
points=[]
indexer=Indexer()
h,w=get_window_size(src)
win_name='get_points'
cv.namedWindow(win_name,cv.WINDOW_NORMAL)
cv.resizeWindow(win_name,width=w,height=h)
cv.imshow(win_name,src)
cv.setMouseCallback(win_name,on_EVENT_LBUTTONDOWN,
param={'src':src,'window':win_name,'indexer':indexer,'points':points})
cv.waitKey(0)
cv.destroyAllWindows()
iflen(points)>4:
returnpoints[0:4]
#print(points)
#points=[(2,14),(90,50),(87,194),(1,204)]
returnpoints

#输入cv.imread后的图片,展示图片长什么样
defshow_img(src):
win_name='show_img'
h,w=get_window_size(src)
cv.namedWindow(win_name,cv.WINDOW_NORMAL)
cv.resizeWindow(win_name,width=w,height=h)
cv.imshow(win_name,src)
cv.waitKey(0)
cv.destroyAllWindows()

将图片截取,并按照指定的长宽比恢复成矩形

defphoto_cut_restore(src,points,H,W):

target_points=[(0,0),(W,0),(W,H),(0,H)]
points,target_points=np.array(points,dtype=np.float32),np.array(target_points,dtype=np.float32)
M=cv.getPerspectiveTransform(points,target_points)
#print('透视变换矩阵:',M)

result=cv.warpPerspective(src_copy,M,(0,0))
result=result[:H,:W]
win_name='Result'
cv.namedWindow(win_name,cv.WINDOW_NORMAL)
cv.resizeWindow(win_name,width=W,height=H)
cv.imshow(win_name,result)
cv.waitKey(0)
cv.destroyAllWindows()
returnresult

主程序

if__name__=='__main__':

path='./1.jpg'
src=cv.imread(path)
src_copy=src.copy()

show_img(src)


W=20
H=20
#points=[(112,308),(175,310),(176,369),(113,369)]

points=get_points(src)
n=20
W=int(W*n)
H=int(H*n)

result=photo_cut_restore(src_copy,points,H,W)

output_file='result.jpg'
cv.imwrite(output_file,result)

三、懒人一键

诶,气不气,好不容易一段段复制完,结果最后居然有一键复制的地方

importcv2ascv
importnumpyasnp

#输入cv.imread后的图片,通过点击四个点选择要裁剪的部分
defget_window_size(src,bound=600):
h,w=src.shape[0],src.shape[1]
ifh>w:
h,w=bound,int(w*bound/h)
else:
h,w=int(h*bound/w),bound
return(h,w)


classIndexer:
def__init__(self):
self.id=0

defget_id(self):
self.id=(self.id+1)
return(self.id)


defon_EVENT_LBUTTONDOWN(event,x,y,flags,param):
ifevent==cv.EVENT_LBUTTONDOWN:
img=param['src']
win_name=param['window']
indexer=param['indexer']
points=param['points']

curr_id=indexer.get_id()
points.append((x,y))
print('第{}个顶点:({},{})'.format(curr_id,x,y))

cv.circle(img,(x,y),10,(0,0,255),thickness=2)
cv.putText(
img,
str(curr_id),#文字
(x,y),#坐标
cv.FONT_HERSHEY_PLAIN,
5,#字号
(0,0,255),#字体颜色
thickness=2#粗细
)

cv.imshow(win_name,img)

#输入cv.imread后的图片,通过点击四个点选择要裁剪的部分
defget_points(src):
points=[]
indexer=Indexer()
h,w=get_window_size(src)
win_name='get_points'
cv.namedWindow(win_name,cv.WINDOW_NORMAL)
cv.resizeWindow(win_name,width=w,height=h)
cv.imshow(win_name,src)
cv.setMouseCallback(win_name,on_EVENT_LBUTTONDOWN,
param={'src':src,'window':win_name,'indexer':indexer,'points':points})
cv.waitKey(0)
cv.destroyAllWindows()
iflen(points)>4:
returnpoints[0:4]
#print(points)
#points=[(2,14),(90,50),(87,194),(1,204)]
returnpoints

#输入cv.imread后的图片,展示图片长什么样
defshow_img(src):
win_name='show_img'
h,w=get_window_size(src)
cv.namedWindow(win_name,cv.WINDOW_NORMAL)
cv.resizeWindow(win_name,width=w,height=h)
cv.imshow(win_name,src)
cv.waitKey(0)
cv.destroyAllWindows()

defphoto_cut_restore(src,points,H,W):

target_points=[(0,0),(W,0),(W,H),(0,H)]
points,target_points=np.array(points,dtype=np.float32),np.array(target_points,dtype=np.float32)
M=cv.getPerspectiveTransform(points,target_points)
#print('透视变换矩阵:',M)

result=cv.warpPerspective(src_copy,M,(0,0))
result=result[:H,:W]
win_name='Result'
cv.namedWindow(win_name,cv.WINDOW_NORMAL)
cv.resizeWindow(win_name,width=W,height=H)
cv.imshow(win_name,result)
cv.waitKey(0)
cv.destroyAllWindows()
returnresult


if__name__=='__main__':

path='./3.jpg'
src=cv.imread(path)
src_copy=src.copy()

#show_img(src)


W=20
H=20
#points=[(124,182),(181,177),(180,243),(125,266)]
points=get_points(src)
print(points)
n=20
W=int(W*n)
H=int(H*n)

result=photo_cut_restore(src_copy,points,H,W)

output_file='result.jpg'
cv.imwrite(output_file,result)

看完了这篇文章,相信你对“Python图片处理之图片裁剪的示例分析”有了一定的了解,如果想了解更多相关知识,欢迎关注恰卡编程网行业资讯频道,感谢各位的阅读!

发布于 2021-05-30 14:04:21
分享
海报
166
上一篇:python b站视频下载的示例 下一篇:怎么用Python进行栅格数据的分区统计和批量提取
目录

    推荐阅读

    忘记密码?

    图形验证码