某音刘畊宏女孩字符动画python-opencv实现

160 阅读1分钟

编程之余,刷某音,发现有个很有意思的,由于不能传视频,如图所示:

lgh.png 有个女程序员将刘畊宏女孩跳舞视频做成了字符串动画效果。 援引某语言之父的话:别BB,直接给我看代码。 那么我用python-opencv复现一下吧:(人生苦短,我用python)

import cv2 as cv
import numpy as np
import random


def character_painting(frame, K=5):
    if type(frame) != np.ndarray:
        frame = np.array(frame)
    h, w, *_ = frame.shape
    frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    frame_array = np.float32(frame_gray.reshape(-1))
    criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
    flags = cv.KMEANS_RANDOM_CENTERS
    compactness, labels, centroids = cv.kmeans(frame_array, K, None, criteria, 10, flags)
    centroids = np.uint8(centroids)
    centroids = centroids.flatten()
    centroids_sorted = sorted(centroids)
    centroids_index = np.array([centroids_sorted.index(value) for value in centroids])
    bright = [abs((3 * i - 2 * K) / (3 * K)) for i in range(1, 1 + K)]
    bright_bound = bright.index(np.min(bright))
    shadow = [abs((3 * i - K) / (3 * K)) for i in range(1, 1 + K)]
    shadow_bound = shadow.index(np.min(shadow))
    labels = labels.flatten()
    labels = centroids_index[labels]
    labels_picked = [labels[rows * w:(rows + 1) * w:2] for rows in range(0, h, 2)]
    canvas = np.zeros((3 * h, 3 * w, 3), np.uint8)
    canvas.fill(255)
    y = 8
    for rows in labels_picked:
        x = 0
        for cols in rows:
            if cols <= shadow_bound:
                cv.putText(canvas, str(random.randint(2, 9)),
                            (x, y), cv.FONT_HERSHEY_PLAIN, 0.45, 1)
            elif cols <= bright_bound:
                cv.putText(canvas, str("-"), (x, y),
                            cv.FONT_HERSHEY_PLAIN, 0.4, 0, 1)
            x += 6
        y += 6
    return canvas

if __name__ == '__main__':
    video = cv.VideoCapture('D:/dance.mp4')
    if video.isOpened():
        open, frame = video.read()
    else:
        open = False

    while open:
        ret, frame = video.read()
        if frame is None:
            break
        if ret == True:
            img = cv.resize(frame, (300, 300))
            str_img = character_painting(img)
            cv.imshow('result', str_img)

            if cv.waitKey(10) & 0xff == 27:
                break

    video.release()
    cv.destroyAllWindows()
```
```
由于不能上传视频,那么复现视频截图如下:
![lgh2.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ef1791af01fd4f7f82dce318c28654ea~tplv-k3u1fbpfcp-watermark.image?)
动手玩一玩吧,欢迎点赞