废话不多说,先看看效果。
1.先讲一下环境搭配
小编用的IDE是VS2019,配置了opencv 4.6.0,版本不一定要相同。相信手眼通天的大家早就一定会配的好的。不过要实现本例,这里小编提几个醒。
必须是Debug x64模式,不然运行报错的。
确保这几个包含目录和库目录已经有了opencv。
还有这个附加依赖项不要忘了。
还有,我们要有个图形库。这里大家要在网上自己下载graphics.h这个库,或者下载一个最简单的库easyx.h就行了 (小编亲测有效) ,用来显示源视频和图形画。
至于这几个库和头文件,其实是自带的。
#include<windows.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")
2.基本原理
其实整体原理很简单,我们利用opencv的一些库函数,先获取视频(相对路径),再用流的方法读取视频中每一帧图片,将3通道的RGB图片转换为2通道的GRAY图片,然后循环读取各个像素的灰度值,将其除以256乘以字符串的长度就是index,转换成的字符就是str[index]。这个字符串是自己敲的。
const char* str = "@#$%&!=+*,';+~. ";
通常由复杂到简单,其实这里就是电脑键盘第二排上的哟(^_^),当然你也可以更改。
循环输出每一行的字符串到初始化的窗口上。详细见下面代码。
3.贴代码
#include<string>
#include<iostream>
#include<cstdio>
#include<opencv2/opencv.hpp>
#include<graphics.h>
#include<windows.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")
using namespace std;
using namespace cv;
int main() {
initgraph(960, 640);//图形库初始化一个960*640的窗口
setbkcolor(BLACK);
cleardevice();
settextstyle(12, 0, "楷体");//这个楷体很重要,不然每一行都对不齐
setbkmode(TRANSPARENT);
VideoCapture mvideo("./video1.mp4");
const char* str = "@#$%&!=+*,';+~. ";//通常由复杂到简单
int len = strlen(str);
BeginBatchDraw();//开启双缓冲绘图,因为要显示在窗口上
Mat frame;
Mat show;
string text;
int index = 0;
while (1)
{
mvideo >> frame;
if (frame.empty())
{
printf("视频未找到");
break;
}
cvtColor(frame, frame, COLOR_BGR2GRAY);//RBG转GRAY
//转换每一帧图片大小
resize(frame, show, Size(300, 150));
resize(frame, frame, Size(150, 50));
cleardevice();
for (int x = 0; x < frame.rows; x++)
{
for (int y = 0; y < frame.cols; y++)
{
int grayval = frame.at<uchar>(x, y);//每个像素点的灰度值
index = grayval / 256.0 * len;
text += str[index];//这里折比换算成index,将对应的各种字符加在后面
}
outtextxy(0, x * textheight(str[index]), text.data());
//图形库操作,打印一行字符
text.clear();
}
imshow("视频转字符画", show);//源视频也一起显示一下
int key = cv::waitKey(10);
if (key == 32) //32是空格键哟
break;
FlushBatchDraw();
}
return 0;
}
这是小编第一次写文章,点个赞再走吧。