from PIL import Image
# 打开图片,path路径
img=Image.open(path)
# 如果我要剪切图片,我可以用crop方法
# 可是,我怎么知道我需要剪切的图片的位置,
# crop方法需要
# 左上角的坐标,右下角坐标
可是,我怎么会知道,我需要剪切的图片的左、右坐标?难道慢慢尝试,还是
要用opencv去寻找轮廓,可是假如我需要的地方,opencv就是找不到,就是需要自己剪切。
可以尝试,也行。。。
我希望我打开一张图片,
在我希望剪切的地方画个东西,比如矩形,就可以得到所需要剪切的图片的坐标,就可以剪切了。
很明显,opencv可以实现。
# 导包
import cv2 as cv
import prettytable as pt
import numpy as np
class seek_place:
def __init__(self,show=False):
self.tangle = [0, 0, 0, 0]
# 矩形的四个角的初始化
self.start = [0, 0]
# 用来存放点击位置的坐标
self.click = False
self.data = []
# 数据的保存
self.show=show
# 是否展示,默认为Flase
def get_size(self, path):
img = cv.imdecode(np.fromfile(path, dtype=np.uint8), -1)
w, h, _ = img.shape
return h, w
# 得到大小,图片不同,窗口的大小也不同,而且不用imread,因为在图片的路径有中文不能读取成功
def draw(self, path):
cv.namedWindow('tu_xiang', 0)
cv.resizeWindow('tu_xiang', self.get_size(path))
cv.setMouseCallback('tu_xiang', self.call_back)
# 鼠标的回调
while cv.waitKey(1) != 27:
# 退出按Esc
img = cv.imdecode(np.fromfile(path, dtype=np.uint8), -1)
pt1 = (self.tangle[0], self.tangle[1])
pt2 = (self.tangle[2], self.tangle[3])
cv.rectangle(img, pt1, pt2, (255, 0, 0), 2)
# 画矩形
cv.imshow('tu_xiang', img)
return self
# 返回self,为了链式调用
def call_back(self, event, x, y, flags, param):
if event == cv.EVENT_LBUTTONDOWN:
# 按下左键,得到位置,改变参数self.click
self.start[0] = x
self.start[1] = y
self.click = True
if event == cv.EVENT_MOUSEMOVE:
# 鼠标移动
if self.click:
self.tangle[0] = self.start[0]
self.tangle[1] = self.start[1]
self.tangle[2] = x
self.tangle[3] = y
if event == cv.EVENT_LBUTTONUP:
#放开左键
tb = pt.PrettyTable()
tb.field_names = ['左上角的坐标', '右下角的坐标:', '中心点的坐标:']
left_palce = (self.tangle[0], self.tangle[1])
right_palce = (self.tangle[2], self.tangle[3])
center_place = [int((self.tangle[0] + self.tangle[2]) / 2), int((self.tangle[1] + self.tangle[3]) / 2)]
tb.add_row([tuple(left_palce), tuple(right_palce), tuple(center_place)])
if not self.data:
self.data.append([(*left_palce, *right_palce), center_place])
# 得到数据
else:
# 为了得到最后一次的数据,只能保存一个
self.data.clear()
self.data.append([(*left_palce, *right_palce), center_place])
if self.show:
#如果需要展示==prettable
print(tb)
self.click = False
#改变参数
def get_data(self):
if self.data:
return self.data
else:
None
#得到数据
比如是这样的
[[(467, 184, 910, 783), [688, 483]]]
最里面的那个元组的前两个数据是左上角坐标,后两个是右下角坐标,我把二者和为一个元组了,取出来直接用,假如需要其他需要,再提取数据
元组后面有个列表,看正文,这个是画的矩形的中心点的坐标。(取整了)
import cv2 as cv
import prettytable as pt
import numpy as np
from init import picturepath
from PIL import Image
# 完整导包
path = picturepath + '/31.jpg'
#picturnpath 图片路径
data=seek_place(show=True).draw(path).get_data()
for i in data:
box=i[0]
# 或者 box=data[0][0]
img=Image.open(path)
a=img.crop(box)
a.save('2.jpg')
给出一张图片
比如我要这样剪切
结果
有待修改,如果不是矩形,假如我想剪的是圆形,或者其他形状。。。
只用opencv好像也可以剪切,我比较菜,先这样把。
当然,结合pypt5,更美观。
(为什么不用ps,或者其他修图工具,哈哈哈哈哈哈哈哈)