2021-11-11

内容概要

  1. flask封装 hash分镜、hist分镜
  2. scipy聚类提取色彩

最终结果:


hash&hist分镜.png
视频帧颜色提取.png

知识点

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)

  1. 简单排序直接用sorted()
  2. 本次实例中,针对元组构成列表则需要用到参数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")

  1. https://blog.csdn.net/qq_40353220/article/details/108217345

  2. https://www.runoob.com/w3cnote/python-func-decorators.html 。。对于这个里面提到的func(*args, **kwargs)解释:
    https://blog.csdn.net/zhurui_idea/article/details/62045072

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容