内容概要
- flask封装 hash分镜、hist分镜
- scipy聚类提取色彩
最终结果:


知识点
1.flask
flask框架老师并没有仔细讲,但的确卡了很多bug,也非常不理解它到底是干啥的。在网上到处乱逛大约知道,flask就是让我们通过python快速搭建一个网站。
首先是问同学,得到关于@app.route()的理解。所谓根路由(‘/’)和(‘/hash’)
简单理解就是跟路由,运行返回的网址“http://127.0.0.1:5008/”返回的是index.html里面写的东西;
“http://127.0.0.1:5008/hash”返回的是hash.html的内容
from flask import Flask # 导入Flak类
app = Flask(__name__) # 接受一个参数__name__
# 装饰器的作用是将路由映射到视图函数index
@app.route('/')
def hello_world():
return 'Hello World!'
# flask应用程序实例的run方法启动web服务器
if __name__ == '__main__':
app.run()
标准的flask框架就长这样,反正首先需要有一个全局管理对象 “app”,作为flask应用对象,需要接受一个参数"——name__” 。
然后使用app.route装饰器,进一步定义视图路由什么的。
最后执行app.run就可以启动服务了。默认Flask只监听虚拟机的本地127.0.0.1这个地址,端口为5000。[1]
至于这个name ,传进去的是一个模块的名字,就是当前目录。当前目录直接会被作为工程目录。
至于这个装饰器,据说是python的重要部分,反正就是可以函数套函数,把函数当成参数传入一个函数。 实现了修改函数的功能。[2]
python小回顾
render_template
1、可以有很多个参数,第一个一定是模板的名字
2、可以传字典、列表、单个变量等等,还可以传函数,在模板中调用函数
Python排序:
sorted(iterable, cmp=None, key=None, reverse=False)
- 简单排序直接用sorted()
- 本次实例中,针对元组构成列表则需要用到参数key
a=[('a',3),('b',7),('w',4),('k',1)]
sorted(a,key=lambda x:x[0])
lambda是隐函数,这句命令就是按照列表里第一个元素排列
<u>https://www.cnblogs.com/zle1992/p/6271105.html</u>
Lambda
源代码
哈希均值和直方图分镜 都利用了 离线计算、在线展示的思想,即先跑出结果,直接网页调用呈现就好
哈希均值比较程序
import cv2
import matplotlib.pyplot as plt
from PIL import Image
from flask import Flask, render_template
import os
# # os.getcwd()
# app = Flask(__name__)
# 均值哈希算法
def aHash(img):
img = cv2.resize(img, (8, 8)) # 缩放为8*8
# 转化为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
s = 0 # 像素和初值;
hash_str = "" # hash 值初值
# 遍历累加求像素和
for i in range(8):
for j in range(8):
s = s + gray[i, j]
# 求平均灰度
avg = s / 64
# 灰度大于平均值为1,相反为0生成图片hash值
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)
# hash长度不同则返回-1代表传参出错
if len(hash1) != len(hash2):
return -1
# 遍历判断
for i in range(len(hash1)):
# 不相等则n计数+1,n最终为相似度
if hash1[i] != hash2[i]:
n = n + 1
# sim=n/60
return n
def genFrame():
v_path = "static/ghz.mp4"
image_save = "static/hash"
if not (os.path.exists(image_save)):
print(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()
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.imwrite("./static/pic/image{}.jpg".format(i), img)
for i in range(549):
img1 = cv2.imread("./static/pic/image{}.jpg".format(i))
img2 = cv2.imread("./static/pic/image{}.jpg".format(i + 1))
hash1 = aHash(img1)
hash2 = aHash(img2)
n = cmpHash(hash1, hash2)
if (n > 20):
# print("均值哈希相似度:",n/64)
cv2.imwrite("./static/hash/image{}.jpg".format(i + 1), img2)
print("over")
直方图比较程序
"""
@Time : 2021/11/10 19:45
@Author : kong
@File : compareImageHist.py
"""
import cv2
import os
# 通过得到RGB每个通道的直方图来计算相似度
def classify_hist_with_split(image1, image2, size=(272, 480)):
# 图像resize
image1 = cv2.resize(image1, size)
image2 = cv2.resize(image2, size)
# 分离RGB通道
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)):
print(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(248):
_, img2 = cap.read()
n = classify_hist_with_split(img1, img2)
# print(n)
if (n < 0.6):
cv2.imwrite('static/hist/image{}.jpg'.format(i), img1)
img1 = img2
genFrame()
聚类色彩算法程序
"""
聚类色彩
@Time : 2021/11/11 22:59
@Author : kong
@File : imagecolor.py
"""
import numpy as np
from scipy.cluster.vq import vq, kmeans, whiten
import matplotlib.pyplot as plt
from PIL import Image
def colorz(filename, n=3):
img = Image.open(filename)
# 使用thumbnail缩略图
img=img.rotate(-90)
img.thumbnail((200, 200))
w, h = img.size
print(w, h)
print('w*h=', w * h)
# plt.axis('off')
# plt.imshow(img)
# plt.show()
points = []
for count, color in img.getcolors(w * h): # getcolors()返回此圖像中使用的顏色列表。
points.append(color)
return points
def kmeansColor(img,n):
points=colorz(img,3)
fe=np.array (points,dtype=float)
codebook, distortion = kmeans(fe, n)
centers = np.array(codebook, dtype=int)
return centers
main.py文件
from flask import Flask, render_template
import os
import cv2
import imagecolor
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)
for i in range(int(fc)):
_, img = cap.read()
cv2.imwrite('static/pic/image{}.jpg'.format(i), img)
@app.route('/') # 根路由器
def index():
# #return "Hi,Flask!"
# genFrame()
# if not picname:
# picname='static/pic/image0.jpg' # 啥意思
pic = 'static/pic/image'
framecount = 249
imgcolors=imagecolor.kmeansColor('static/pic/image0.jpg',5)
return render_template('index.html', framecount=framecount, pic1=pic, imgcolors=imgcolors)
@app.route('/hash')
def hash():
path = 'static/hash'
filename = os.listdir(path)
print(type(filename))
print(filename)
imagecount = len(filename)
return render_template('hash.html', imgcount=imagecount, filename=filename)
@app.route('/shot')
def shot():
path = 'static/hash'
filename = os.listdir(path)
framecount = len(filename)
filename.sort(key=lambda x: int(x[5:-4]))
print(filename)
print(type(filename))
print(filename)
path = 'static/hist'
histfile = os.listdir(path)
histcount = len(histfile)
histfile.sort(key=lambda x: int(x[5:-4])) # 排序 根据 5到倒数4
return render_template('shot.html', filename=filename, framecount=framecount, histfile=histfile,
histcount=histcount)
if "__main__" == __name__:
app.run(port="5008")