一、PyCharm开发环境与简单应用
- PyCharm是一种Python的集成开发环境,可以高效的进行语言开发,并且支持支持专业Web开发。
- Flask是一个Web应用框架,使用PyCharm编写。
安装并启动PyCharm后,需要先安装要用的模块,包括Flask、cv2等等。
安装方法:点击setting进入如下页面,点击Package上方的加号,搜索要用到的模块进行安装。
注意:
- 在安装cv2的时候,系统提示我的模块版本过低,我使用了在命令行输入如下命令的方法安装,安装成功。
C:\Users\95378\PycharmProjects\pythonProject\venv\Scripts\python.exe -m pip install opencv-python -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
- 在安装PIL的时候也出现了错误。在网上查了一下发现,PIL较多用于2.7版本的Python中,到python3版本已经用Pillow代替PIL了。所以应该安装Pillow库,引入的命令方式也从:import image变为:from PIL import Image
安装成功后可以利用PyCharm进行一些简单的编写。
1.在PyCharm中创建新项目(new project)
2.在main.py中录入如下代码(如果main.py中有内容可删除)
from flask import Flask,render_template
app=Flask(__name__)
@app.route('/')
def index():
#return "Hi,Flask!"
return render_template('index.html')
if "__main__"==__name__:
app.run(port="5008")
3.创建templates文件夹,用于存放html模板(PyCharm要求文件夹一定是这个名字,才会出现模板)
4.在templates里新建一个HTML文件,命名为index.html,输入如下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>分镜</title>
</head>
<body>
视频分镜
</body>
</html>
打开网页,就可以看到网页上出现一行字
还可以通过python将视频切帧。在项目中新建static文件夹,用于存放视频、图片等信息。
main.py代码中定义genFrame函数,用于视频切帧,将图像保存到static/pic文件中。
from flask import Flask,render_template
import os
import cv2
app = Flask(__name__)
def genFrame(): #定义函数切帧
v_path = "static/ghz.mp4"
image_save = "static/pic"
if not(os.path.exists(image_save)):
os.mkdir(image_save)
cap=cv2.VideoCapture(v_path)
fc=cap.get(cv2.CAP_PROP_FRAME_COUNT)
print(fc)
for i in range(int(fc)):
_,img=cap.read()
cv2.imwrite("static/pic/image{}.jpg".format(i),img)
@app.route('/')
def index(): #定义函数将framecount和pic传到html中
#return 'Hi, Flask!'
genFrame() #运行上面的函数
framecount=249 #根据文件中的帧数输入数字。这一行是指将py文件的帧数传到html中
pic = "static/pic/image"
return render_template("index.html", pic1=pic, framecount=framecount)
if "__main__" == __name__:
app.run(port='5001')
html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask分镜</title>
</head>
<body>
视频分镜
<br>
<video width="640" height="480" controls autoplay>
<source src="static/ghz.mp4" type="video/mp4">
</video>
<br>
帧数:{{framecount}} <!--括号里的是看有没有传成功-->
<br>
{% for i in range(framecount)%}<!--在html写python代码的模板,这是开头,一个循环-->
<img height="40" src="{{pic1}}{{i}}.jpg">
image{{i}}
{%endfor%}<!--这是结尾-->
</body>
</html>
运行结果(图片共有249帧):
二、在网页中加载视频分镜功能
在flask架构的基础上,将视频分镜的代码片段合并到main.py文件中,再在html中加载出视频,就可以实现在网页加载视频分镜。
哈希均值算法,Python代码:
#哈希均值算法
from flask import Flask,render_template
import os
import cv2
app = Flask(__name__)
def aHash(img): #定义哈希值函数
img = cv2.resize(img, (8, 8))
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
s = 0
hash_str = ''
for i in range(8):
for j in range(8):
s = s + gray[i, j]
avg = s / 64
for i in range(8):
for j in range(8):
if gray[i, j] > avg:
hash_str = hash_str + '1'
else:
hash_str = hash_str + '0'
return hash_str
def cmpHash(hash1, hash2): #定义比较哈希值的函数
n = 0
print(hash1)
print(hash2)
if len(hash1) != len(hash2):
return -1
# 遍历判断
for i in range(len(hash1)):
# 不相等则n计数+1,n最终为相似度
if hash1[i] != hash2[i]:
n = n + 1
return n
def genFrame(): #定义函数放入视频分镜的代码
v_path = "static/ghz.mp4"
image_save = "static/hash"
if not(os.path.exists(image_save)):
os.mkdir(image_save)
cap=cv2.VideoCapture(v_path)
fc=cap.get(cv2.CAP_PROP_FRAME_COUNT)
print(fc)
_,img1=cap.read() #读取第一张图像
cv2.imwrite("static/hash/image{}.jpg".format(0),img1)
for i in range(int(fc)-1):
_,img2 = cap.read()
hash1 = aHash(img1)
hash2 = aHash(img2)
n = cmpHash(hash1, hash2)
if (n>35): #数值越大,分的帧数越小
cv2.imwrite("static/hash/image{}.jpg".format(i), img2)
img1=img2
@app.route('/hash')
def index(): #定义函数将framecount和hash传到html中
genFrame()
path='static/hash'
filename = os.listdir(path)
framecount=len(filename)
filename.sort(key= lambda x:int(x[5:-4]))
print(filename)
return render_template("hash.html", filename=filename, framecount=framecount)
if "__main__" == __name__:
app.run(port="5008")
HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hash分镜</title>
</head>
<body>
视频分镜
<br>
<video width="640" height="480" controls autoplay>
<source src="static/ghz.mp4" type="video/mp4">
</video>
<br>
帧数:{{framecount}}
<br>
{% for i in filename %}
<img height="40" src="static/hash/{{i}}">
{{i}}
{% endfor %}
</body>
</html>
运行结果:
直方图算法,Python代码:
from flask import Flask,render_template
import os
import cv2
app = Flask(__name__)
# 定义函数比较RGB每个通道的直方图计算相似度
def classify_hist_with_split(image1, image2, size=(256, 256)):
image1 = cv2.resize(image1, size)
image2 = cv2.resize(image2, size)
sub_image1 = cv2.split(image1)
sub_image2 = cv2.split(image2)
sub_data = 0
for im1, im2 in zip(sub_image1, sub_image2):
sub_data += calculate(im1, im2)
sub_data = sub_data / 3
return sub_data
# 计算单通道的直方图的相似值
def calculate(image1, image2):
hist1 = cv2.calcHist([image1], [0], None, [256], [0.0, 255.0])
hist2 = cv2.calcHist([image2], [0], None, [256], [0.0, 255.0])
degree = 0
for i in range(len(hist1)):
if hist1[i] != hist2[i]:
degree = degree + (1 - abs(hist1[i] - hist2[i]) / max(hist1[i], hist2[i]))
else:
degree = degree + 1 # 统计相似
degree = degree / len(hist1)
return degree
#定义根目录,分镜
def genFrame():
v_path = "static/ghz.mp4"
image_save = "static/hist"
if not(os.path.exists(image_save)):
os.mkdir(image_save)
cap=cv2.VideoCapture(v_path)
fc=cap.get(cv2.CAP_PROP_FRAME_COUNT)
print(fc)
_, img1=cap.read() #读取第一张图像
cv2.imwrite("static/hist/image{}.jpg".format(0), img1)
print(int(fc))
for i in range(int(fc)-1):
_, img2 = cap.read()
n = classify_hist_with_split(img1, img2)
if (n<0.4):
cv2.imwrite("static/hist/image{}.jpg".format(i), img2)
img1=img2
genFrame()
@app.route("/hist")
def index():
pic = "static/hist"
filename=os.listdir(pic)
count=int(len(filename))
filename.sort(key=lambda x: int(x[5:-4]))
print(filename)
return render_template("hist.html", pic=pic, filename=filename, count=count)
if "__main__" == __name__ :
app.run(port="5009")
HTML代码同上
运行结果: