1, 记录一些代码-opencv 图片视频裁剪
发布于 2022年 02月 26日 15:33
记录一些代码
# 裁剪矩形图片
def clipImage(file, p1, p2):
img = cv2.imread(file, cv2.IMREAD_COLOR)
return img.copy()[p1[0]:p2[0], p1[1]:p2[1]]
# 裁剪矩形图片
def clipMat(mat, p1, p2):
return mat.copy()[p1[0]:p2[0], p1[1]:p2[1]]
p1 = (817, 898)
p2 = (2183 , 1666)
# 视频读, 显示
cap = cv2.VideoCapture('D:/crawler/code/MoviePy/donggandimo_01/mask1.mp4')
fourcc = cv2.VideoWriter_fourcc(*'XVID')
videoWriter = cv2.VideoWriter('D:/crawler/code/MoviePy/donggandimo_01/mask1_clip.mp4', fourcc, 15.0, (768, 1366))
i = 0
ret = True
while cap.isOpened() and ret:
ret, frame = cap.read()
if ret:
out = clipMat(frame, p1, p2)
print(out.shape[:2])
# cv2.imshow('',out)
# cv2.waitKey(100)
videoWriter.write(out)
print(i)
i += 1
cap.release()
cv2.destroyAllWindows()
中心点坐标系变为左上角坐标系
# -*- coding: utf-8 -*-
import json
import math
import time
'''
将transform数据封装成方法
'''
# 角度转弧度
def degreeToRad(r):
return r * math.pi / 180
# 角度转为360以内
def degreeConvertIn360(r):
return r%360
# 获取缩放后的大小
def get_size(_x, _y, scale):
return (_x*scale[0], _y*scale[1])
# 位置信息 x: 素材宽, y:素材高, anchor: 锚点在图片中,rotate:角度, sacle:缩放, anchor_pos:锚点位置
def get_postion(_x, _y, anchor, rotate, scale, anchor_pos):
print((_x, _y, anchor, rotate, scale, anchor_pos))
p = anchor_pos
s = scale
a = anchor
_r = rotate
# 左上角的坐标
x = p[0] - a[0] * s[0]
y = p[1] - a[1] * s[1]
r = degreeConvertIn360(_r)
after = ransform((p[0], -p[1]), (x, -y), -_r)
if r >= 0 and r< 90:
after = (after[0] - _y* s[1]*math.sin(degreeToRad(r)), after[1])
elif r >= 90 and r < 180:
r = r - 90
after = (after[0] - _y * s[1] * math.cos(degreeToRad(r)) - _x*s[0]*math.sin(degreeToRad(r)), after[1] - _y * s[1] * math.sin(degreeToRad(r)))
elif r >= 180 and r < 270:
r = r - 180
after = (after[0] - _x * s[0] * math.cos(degreeToRad(r)), after[1]- _x * s[0] * math.sin(degreeToRad(r)) - _y * s[1] * math.cos(degreeToRad(r)))
elif r >= 270 and r < 360:
r = r - 270
after = (after[0], after[1] - _x * s[0] * math.cos(degreeToRad(r)))
else:
print("######### Error rotate: %s" % (_r))
print("转换后的坐标: (%s, %s), 角度为: %s" % (after[0], after[1],_r))
return (after[0], after[1])
# 角度变换 点a:目标点 点a0:旋转点, r:旋转角度(逆时针旋转)
def ransform(a0, a, r):
x0 = a[0] - a0[0]
y0 = a[1] - a0[1]
# rad = degreeToRad(r)
rad = math.radians(r)
return (x0*math.cos(rad)-y0* math.sin(rad) + a0[0], -(x0 * math.sin(rad)+ y0 *math.cos(rad) + a0[1]))
if __name__ == "__main__":
# import numpy as np
# from moviepy.editor import *
# import playutil
#
# bg = np.zeros((500, 500, 3), np.uint8)
# bg1 = np.zeros((400, 10, 3), np.uint8)
# bg1.fill(255)
# def get_pos(t):
# h, w = bg1.shape[:2]
# print('w: %s, h: %s' % (w, h))
# return get_postion(w, h, (w/2, h/2), math.sin(t/3)*360, (1, 1), (250, 250))
# # return transformutil.get_postion(w, h, (w/2, h/2), 45, (1, 1), (w/2, h/2))
#
# bg_clip = ImageClip(bg).set_duration(200).set_fps(15)
# bg_clip1 = ImageClip(bg1).set_position(get_pos).set_fps(55).set_duration(20).rotate(lambda t:math.sin(t/3)*360)
#
# out = CompositeVideoClip([bg_clip, bg_clip1]).set_duration(20)
# playutil.play(out, False)
pos = get_postion(100, 100, (50, 50), 0, (0.2, 0.2), (50, 50))
print(pos)
图片裁剪
# 等比例缩放, 背景用原图片模糊处理
# w, h: 处理后的图片大小
def convertImage(file, w, h):
img = cv2.imread(file, cv2.IMREAD_COLOR)
img_h, img_w = img.shape[:2]
# img = ImageClip(file)
bgImg = cv2.resize(img, (w, h))
bgImg = cv2.GaussianBlur(bgImg, (25, 25), 0)
if img_w / img_h > w/h:
print((img_w, img_h))
img = cv2.resize(img, (w,int(img_h/(img_w/w))))
else:
img = cv2.resize(img, (int(img_w/(img_h/h)),h))
img_h, img_w = img.shape[:2]
bgImg[int((h-img_h)/2):int((h-img_h)/2)+ img_h, int((w-img_w)/2):int((w-img_w)/2)+ img_w] = img
# result = result.set_start(0).set_duration(4)
# result.write_videofile("result.mp4", fps=24, codec="libx264", bitrate="1000000")
return bgImg
图片上写字
# coding:utf-8
import cv2
import numpy as np
from PIL import ImageFont, Image, ImageDraw
def getFont():
return '../Engine/ttf/ss.ttf'
def showframe0(video):
frame = video.get_frame(0)
cv2.imshow('aa', frame)
cv2.waitKey(0)
def showim(frame):
h, w = frame.shape[:2]
cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
cv2.resizeWindow("frame", (int(w / 2), int(h / 2)));
cv2.imshow('frame', frame)
cv2.waitKey(1000)
def play(video, hasframecount):
iter = video.iter_frames()
i1=0
# print(type(iter))
for frame in iter:
frame = frame.copy().astype(np.uint8)
print(frame[0,0])
# frame = make_frame(0)
print(frame.shape)
img = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
# img = frame
istr = str(i1)
h, w = img.shape[:2]
if hasframecount:
text = writeText(100,50*len(istr),istr,100,(255,0,0), '../aiqingtuya/ss.ttf')
th, tw = text.shape[:2]
img[0:th, 0:tw] = text
# cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
# cv2.resizeWindow("frame", (200 ,200));
cv2.imshow('frame', img)
key = cv2.waitKey(300)
if key == ord('q'):
break
i1 = i1 +1
cv2.destroyAllWindows()
# 实现在指定区域写字
# w:写字区域的宽, h:写字区域的高, x:写的字左上角的x坐标,y:同理 color: 字的颜色, font: 字体的ttf文件路径,
# x1,y1: 写字区域的左上角坐标(超过写字区域不显示)
def getTextMask(text, h, w,img=None, x=0, y=0,x1 =0, y1=0, color=(255, 255, 255), font=getFont(),font_size=None, bg_color=(0,0,0)):
# 修复截取的区域超出图片报错的bug
n = text.count('\n') + 1
if img is None:
canvas_bg = np.zeros((1080, 720, 3), np.uint8)
canvas_bg[:,:,0] = bg_color[0]
canvas_bg[:, :, 1] = bg_color[1]
canvas_bg[:, :, 2] = bg_color[2]
else:
canvas_bg = img.copy()
c_h, c_w = canvas_bg.shape[:2]
canvas = np.zeros((c_h+2*h, c_w+2*w, 3),np.uint8)
canvas[ h:h+c_h, w:w+c_w] = canvas_bg
if font_size is None:
font_size = int((h - 10) / n)
txt_area = canvas[y1+h:y1 + 2*h, x1+w:x1 + 2*w]
out = writeText(h, w, text, font_size, color, font,img=txt_area, x=x, y=y, bg_color=bg_color)
# showim(out)
# cv2.imshow('b', out)
canvas[y1+h:y1 + 2*h, x1+w:x1 + 2*w] = out
# cv2.rectangle(canvas, (x1, y1), (x1+w, y1+h), (0,0,255), thickness=1)
return canvas[h:h+c_h, w:w+c_w]
# 在图片上写字
def writeText(h, w,text, size, color, ttf=getFont(), img=None, x =None, y=None, bg_color=(0,0,0)):
color = (color[2], color[1], color[0])
if img is None:
img = np.zeros((h, w, 3), np.uint8)
img[:, :, 0] = bg_color[0]
img[:, :, 1] = bg_color[1]
img[:, :, 2] = bg_color[2]
if x is None:
x = 0
if y is None:
y=0
cv2_im = cv2.cvtColor(img, cv2.COLOR_BGRA2RGBA)
pil_im = Image.fromarray(cv2_im)
draw = ImageDraw.Draw(pil_im)
font = ImageFont.truetype(ttf, size, encoding="utf-8")
draw.text((x, y), text, color, font=font)
cv2_text_im = cv2.cvtColor(np.array(pil_im), cv2.COLOR_RGB2BGR)
# cv2.imshow("Video", cv2_text_im)
# cv2.waitKey(0)
return cv2_text_im
# 处理多行文字居中对齐
def handlerTextLine(*txt):
max = 0
s = []
for i in txt:
l = 0
for ch in i:
if isChinese(ch):
l = l +2
else:
l = l + 1
if l > max:
max = l
print(max)
for i in txt:
l = 0
for ch in i:
if isChinese(ch):
l = l + 2
else:
l = l + 1
space_num= int((max-l)/2)
print(str(i)+':'+str(space_num))
s.append(space_num*" "+ i)
return '\n'.join(s)
# 判断单个字符是否为汉字
def isChinese(ch):
if '\u4e00' <= ch <= '\u9fff':
return True
# @hubobo 判断方法
def txtLen(i):
l = 0
for ch in i:
if isChinese(ch):
l = l + 2
elif ch.islower():
l = l + 1
else:
l = l + 1.5
return l
# 判断字符串的长度, 汉字为2个, 字母为1个
def txtLenSelf(i) :
l = 0
for ch in i:
if isChinese(ch):
l = l + 2
else:
l = l + 1
return l
# 实现在图片上写字, 有透明效果
def writeTextWeighted(imput_txt, h, w, img=None, x=0, y=0,x1 =0, y1=0, color=(255, 255, 255), font=getFont(), font_size=None, bg_color=(0,0,0), weight=1):
if img is None:
canvas = np.zeros((1080, 720, 3), np.uint8)
canvas[:, :, 0] = bg_color[0]
canvas[:, :, 1] = bg_color[1]
canvas[:, :, 2] = bg_color[2]
else:
canvas = img
img2 = canvas.copy()
text = getTextMask(imput_txt, h, w, img=img2, x=x, y=y, x1=x1, y1=y1, font_size=font_size, color=color)
out = cv2.addWeighted(img, (1-weight), text,weight, 0)
return out
#
if __name__ == "__main__":
#
#
#
# 1, 写透明字体
# text = handlerTextLine('您好', '娃哈哈', '江山如此多娇')
# # 写透明字
# for i in range(10):
# out = writeTextWeighted(text, 80, 360, img=cv2.imread('../test/cat.jpg', cv2.IMREAD_COLOR), x=0, y=0, x1=180,
# y1=680, color=(255, 0, 0), weight=i / 10)
# cv2.imshow('', out)
# cv2.waitKey(0)
#
#
#
# # 2, 逐字写入
# # txt = '昨夜星辰昨夜风,画楼西畔桂堂东。\n身无彩凤双飞翼,心有灵犀一点通。\n隔座送钩春酒暖,分曹射覆蜡灯红。\n嗟余听鼓应官去,走马兰台类转蓬。'
# # n = txt.count('\n') + 1
# # # 写透明字
# # for i in range(len(txt)+1):
# # input_txt = txt[:i]
# # m = input_txt.count('\n')
# # input_txt =input_txt + ((n-m)*"\n")
# # out = writeTextWeighted(input_txt, 200, 600, img=cv2.imread('../demo/a.jpg', cv2.IMREAD_COLOR), x=0,y=0, x1=0, y1=0, color=(255,0,0), weight=1)
# # cv2.imshow('', out)
# # cv2.waitKey(100)
#
# 3, 从上往下写
txt1 = '李白'
txt2 = '杜甫'
txt1s = '\n'.join(list(txt1))
txt2s = '\n'.join(list(txt2))
# out = pictureutil.writeTextWeighted(txt1s, 500, 800, img=cv2.imread( self.path + 'head.png', cv2.IMREAD_COLOR),
# x=0, y=0, x1=516,
# y1=526, color=(136,245,255), font_size=45, weight=1)
# cv2.namedWindow('a', cv2.WINDOW_NORMAL)
for i in range(max(len(txt1s), len(txt2s))+1):
input_txt1s = txt1s[:i]
input_txt2s = txt2s[:i]
out = getTextMask(input_txt1s, 200, 600, img=cv2.imread('../test/cat.jpg', cv2.IMREAD_COLOR), x=0, y=0, x1=-10,
y1=-10,color=(89,147,255), font_size=25)
# out = writeTextWeighted(input_txt2s, 200, 600, img=out, x=0, y=20, x1=0,
# y1=0, color=(89,147,255), font_size=25, weight=1)
cv2.imshow('a', out)
cv2.waitKey(1000)