基于Opencv的字符画自动生成

其实很早之前就把这个做好了,毕竟要交大作业,为此学了一个星期的Opencv.....还用上了我行将就木的tkinter.....

好吧,我的代码风格不是很好,yysy是第一次尝试类的模式编程

具体的原理就是把图像灰度读入,然后再根据灰度值选择合适的字符,不难吧....

另外,这是我今年的大作业,要抄的话please等到明年,谢谢...

还有,今年寒假学算法,欢迎某位大佬为我的算法笔记指点...

好了好了,废话不说了,说一下使用准则,顺便把答辩时的解释思维附上:

main.py文件不能在有中文的路径下执行,否则字符画的保存将受影响
这是受制于opencv的imwrite的特性
同理:
选择的图片不能在有中文的路径下
这是受制于opencv的imopen

对了,可以用pystaller来生成可执行exe文件,这样可以直接发给你的好朋友zhuang B

基于Opencv的字符画自动生成_第1张图片

 paint.py

基于Opencv的字符画自动生成_第2张图片

import cv2  # 导入opencv
import numpy as np  # 导入 numpy用于生成新画布
import matplotlib.pyplot as plt
Remember1 = None
Remember2 = None
Remember3 = []
class Info(object):  # 初始化相关信息
    def __init__(self, root):
        # 判断输入的类型,如果是视频,传入的是读取完的数据,图片则是原始路径
        if type(root) == str:  # 这里是如果输入的是图片绝对路径
            image = cv2.imread(root, cv2.IMREAD_GRAYSCALE)  # 以灰度图形读入
            length, width = image.shape[1], image.shape[0]  # 获取图片的基本信息
            rate = self.Change_size(length, width)  # 因为有些图片过于大,导致屏幕无法显示,所以这里是获取缩放的比例
            image = cv2.resize(image, (0, 0), fx=rate, fy=rate)  # 根据上面数据缩放图片
            self._height, self._width = image.shape  # 记录最后的实际长宽
            self._gray_info = image  # 将读入的图片信息保存
        else:  # 如果是视频格式, 相比之下省略了读入这一操作
            length, width = root.shape[1], root.shape[0]
            rate = self.Change_size(length, width)
            root = cv2.resize(root, (0, 0), fx=rate, fy=rate)
            self._height, self._width = root.shape
            self._gray_info = root
    @staticmethod
    def Change_size(length, width):
        mutiply_, tem1, tem2 = 1, width, length
        while tem1 > 900 or tem2 > 1900:  # 这两个参数代表如果屏幕想要完全展示的的最大边界
            mutiply_ -= 0.1  # 逐一尝试只到符合
            tem1 = mutiply_ * width
            tem2 = mutiply_ * length
        return mutiply_

class Paint(Info):  # 实际操作
    _use_char = ['.', '-', '=', '+', '#']  # 使用的字符
    @staticmethod
    def Judge(number):  # 判断用哪一个字符,灰度值为255 对其5分
        return number // 52  # 不用51来除是为了防止数组越界
    def New(self):
        Canvas = np.ndarray([self._height, self._width])  # 依据原始图片大小来生成新的画布
        return Canvas
    def Paint_Canvas(self):
        global Remember2, Remember3
        Remember3.clear()
        Canvas = self.New()
        for pr1 in range(0, self._height, 5):  # 每5步判断当前灰度值判断使用何种字符
            tem = []
            for pr2 in range(0, self._width, 5):
                char = self._use_char[self.Judge(self._gray_info[pr1][pr2])]
                tem.append(char)
                cv2.putText(Canvas, char, (pr2, pr1), cv2.FONT_HERSHEY_SIMPLEX,0.1,(255,255,255),1)
            Remember3.append(tem)
        Remember2 = Canvas
        return Canvas  # 将制作好的画布返回

class Vidio(object):  # 视频类
    def __init__(self, root):
        self.sample = cv2.VideoCapture(root, cv2.IMREAD_GRAYSCALE)  # 正常读入视频
    def Show(self):
        if_can = self.sample.isOpened()  # 判断是否可以正常打开
        while if_can:
            tem, flame = self.sample.read(cv2.IMREAD_GRAYSCALE)  # 获取每帧的图像信息
            if flame is None:  # 如果读取的图像为空,结束
                break
            else:
                flame = cv2.cvtColor(flame, cv2.COLOR_BGR2GRAY)  # 转化为灰度图
                used = Paint(flame)  # 将图片置为paint类进行转化
                image = used.Paint_Canvas()
                cv2.imshow('point esc to quit',image)  # 展示
                if cv2.waitKey(10) & 0xFF == 27:  # 等待10ms或者按下退出键结束
                    break

class Picture(Paint):  # 图片类
    def Show(self):
        global Remember1
        image = self.Paint_Canvas()  # 直接转为paint类
        Remember1 = image
        cv2.imshow('image', image)
        # 将关闭模式设为判断窗口是否存在,这样可以避免如果没有按esc关闭导致的程序卡死问题
        while True:
            if cv2.getWindowProperty('image', 0) == -1:  # 如果窗口关闭
                break
            cv2.waitKey(1)

# 判断输入的是图像还是视频
def Judge_form(root):
    vidio_ = ['mp4', 'avi', 'wmv', 'm4v', 'flv', 'f4v']  # 视频常见格式
    Picture_ = ['jpg', 'png', 'bmp']  # 图片常见格式
    root.replace('\\', '/')  # 将'\'转化为'/',防止转义
    if root[-3:] in Picture_:  # 切片判断
        begin = Picture(root)
        begin.Show()
    elif root[-3:] in vidio_:
        begin = Vidio(root)
        begin.Show()

def give_out():
    return Remember1

if __name__ == '__main__':
    pass

 

window_make.py

其实我觉得我的窗口做的稀烂

基于Opencv的字符画自动生成_第3张图片

 

import tkinter as tk  # 导入tkinter
import cv2
from tkinter import filedialog  # 导入 filedialog
import paint  # 导入paint
import expand  # 导入expand
class MakeWindow(object):  # 窗口类
    def __init__(self):
        # 之后所需要的变量
        self.give = None
        self.put = None
        self.entry_text = None
        self._root = tk.Tk()  # 建立窗口
        self._root.geometry('500x400')  # 设置大小
        self.space = ['基于OpenCv的字符画自动生成及其应用','方法一:请输入想打开文件的绝对路径',
                      '方法二:选择文件(路径不要包含中文)', '开始生成']  # 所需要的文字
        self._root.title(self.space[0])

    def Label(self):
        # 标题
        introduce = tk.Label(self._root, text=self.space[0], bg='white', font=('Arial', 15), width=40, height=2)
        # 方法一
        info1 = tk.Label(self._root, text=self.space[1], bg='white',font=('Arial', 10),height=2)
        # 方法二
        info2 = tk.Label(self._root, text=self.space[2], bg='white',font=('Arial', 10),height=2)
        introduce.grid(row=0, column=0, padx=30, pady=20,columnspan=10)
        info1.grid(row=1, column=0,padx=30, pady=10, sticky='w', columnspan=5)
        info2.grid(row=3, column=0,padx=30, pady=10, sticky='w',columnspan=5)

    def Button(self):
        def get_space():  # 获取内容
            self.give = self.put.get()
            paint.Judge_form(self.give)

        def get_path():  # 获得路径
            path = filedialog.askopenfilename(title='请选择文件')
            self.entry_text.set(path)
        # 开始生成
        check = tk.Button(self._root, text=self.space[3],bg='red',height=2,width=10,command=get_space)
        # 选择路径
        Search = tk.Button(self._root, text='选择路径', command=get_path, bg='pink')
        # 保存图片
        Remember1 = tk.Button(self._root, text='保存图片', command=expand.Remember_image, bg='pink')
        # 保存为txt
        Remember2 = tk.Button(self._root, text='保存为txt', command=expand.Form_TXT, bg='pink')
        check.grid(row=5, column=4,)
        Search.grid(row=3, column=6)
        Remember1.grid(row=8, column=2,pady=5)
        Remember2.grid(row=8, column=6,pady=5)

    def Entry(self):  # 输入绝对路径
        self.entry_text = tk.StringVar()
        self.put = tk.Entry(self._root, textvariable=self.entry_text, width=50)
        self.put.grid(row=2, column=0,columnspan=10)

    def Warming(self):
        write = ["注:关闭视频时按esc退出,选择图片时路径不可有中文,视频路径无限制"]
        info2 = tk.Label(self._root, text=write, bg='white', font=('Arial', 10), height=3,width=60)
        info2.grid(row=10,column=1,sticky='w',columnspan=10)

    def Show(self):  # 展示
        self.Label()
        self.Entry()
        self.Button()
        self.Warming()
        self._root.mainloop()


if __name__ == '__main__':
    a = MakeWindow()
    a.Show()

expand.py

基于Opencv的字符画自动生成_第4张图片

import cv2, os, window_make, paint, numpy, random

path = os.getcwd()
dir_name = path + '/this is a dir'
def Create():
    if not os.path.isdir(dir_name):
        os.mkdir(dir_name)

def name():
    ran = "zxcvbnm,dsakfgwa1131234567890-=vcsdhgkcqwertyuiopscdjsvzxcvbnmeywur"
    a = random.sample(ran,10)
    s = ''
    for pr in a:
        s += pr
    return s

def Remember_image():
    Create()
    image = paint.give_out()
    cv2.imwrite(dir_name + '/' + name() + '_new.jpg', image)

def Form_TXT():
    Create()
    put = paint.Remember3
    data = open(dir_name + '/' + name() + '_new.txt','a+')
    for i in range(len(put)):
        for j in range(len(put[i])):
            data.write(str(put[i][j]))
            data.write(' ')
        data.write('\n')
    data.close()

 main.py

一个我觉得很多余但是还是像这样干的文件

import window_make
Finally = window_make.MakeWindow()
Finally.Show()

最后的执行效果

Vedio

看我坤哥:

 Picture

这是一个霸屏我的VS, Wallpaper的动漫角色,虽然我不知道是谁

 另外

再窗口设计这方面此程序还有些许不足,但是我懒的改

对了

大家玩的过程要是要啥问题可以评论,放心,绝对不会改

你可能感兴趣的:(opencv,计算机视觉,人工智能)