【C++】与【openCV】将图片转化为字符画,超详细,新手向

目录

 一、OpenCV的安装配置

二、图片的读取

三、将彩图转为灰度图

四、遍历每一个像素点,转化为字符串

五、保存为txt文件

六、总结

这本是我期末C++的大作业,想上网上参考一下,却发现大多是使用python,真正用到c++和opencv库的少之又少,质量也参差不齐,自己学成之后,希望可以给其他的计算机同学一些参考。

本项目使用到的是 VS

示例图:(在网上随便找的)

效果图:

 一、OpenCV的安装配置

在这里就不重点介绍了,可以参考@wendy_ya大佬的文章,里面详细介绍了OpenCV库的下载安装教程,根据里面的步骤一步步来就可以了。

文章链接:OpenCV概述及安装配置教程_opencv安装-CSDN博客

二、图片的读取

既然要将图片转化为字符串,自然也就要在程序中对图片进行操作,在OpenCV中,我们将使用Mat类型来储存图片的信息。

Mat类我们暂时可以理解为一个矩阵,储存着一张图片的数据,例如,图片每种颜色都是三原色组合而成,那么Mat类型就会储存每一个像素点中,三原色的数值RGB

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>

using namespace cv;

int main()
{
    //使用Mat类型来储存图片的数据
    //图片的读取就要使用到imread函数
     Mat img = imread("R-C.png");  //注意:图片要在当前文件夹中才能直接这么写,否则要加上路径
     
    if (img.empty())
     {
         std::cout << "mat::" << std::endl;
         return -1;
     }
    return 0;
}

 读取函数:  imread(“图片的名称”)

如果图片在当前文件夹中,你可以直接填上图片的名称

如果你想打开其他文件夹中的图片,那你就要加上图片的路径,如“C:\picture\R-C.png”

img.empty()

判断img是否为空,如果空的话就没有必要进行下去,检查图片的路径是否正确

三、将彩图转为灰度图

灰度图是一种只有黑、白和灰色的图像,它是由彩色图像经过灰度化处理得到的。在灰度化处理中,将彩色图像中的每个像素点的红、绿、蓝三个通道的颜色值按照一定的比例加权平均,得到一个灰度值

gray = 0.299 * red + 0.587 * green + 0.114 * blue

转化为灰度图后,图片原本的三原色信息RGB变成只有一个信息gray,我们将跟本这个灰度值来进行字符的转化。

 cvtColor(img, img, COLOR_BGR2GRAY);//将图片转为灰度图
 resize(img, img, Size(), 0.05,0.05);//调整图片的大小

在opencv中我们使用cvtColor来转化图片

 cvtColor(参数1:原图片,参数2:接收转化后的图片,参数3:转化的类型)

第三个参数为COLOR_BGR2GRAY,意思就是告诉程序,我要将这个图片转化为灰度图

调整图片的大小,现在的图片最小都是是十几万的像素点,要是直接转化为字符画的话要很大的屏幕才能看出效果,故而我们调整图片的尺寸,缩小一点,从而可以在一个小区域内也能实现出我们想要的效果。

resize(参数1:原图片,参数2:接收转化后的图片,参数3:Size()照写,参数4、5:长度、宽度与原图像的倍数) 

我们依旧使用img传出,又用img接收,0.05则表示调整图片的长度宽度是原图像的0.05倍 

调整之后的大小对比还是很明显的

四、遍历每一个像素点,转化为字符串

string text; //储存输出的字符串
const char* str = "@W#$OEXC[(/?=^~_. "; //自己准备的要替换的字符串
int index = 0, len = strlen(str), color;

//遍历图片的每一个像素点
for (int x = 0; x < img.rows; x++)
{
    for (int y = 0; y < img.cols; y++)
    {

        color = img.at<uchar>(x, y);
        index = color / 256.0 * len; //将灰度值映射为字符下标
        
        text += str[index];
    }
    
    text += "\n";
}
cout << text << endl;  // 输出每一行的字符串

 使用img.rows 和 img.cols 可以获取到图片的长和宽,然后对图片的每一个像素点进行遍历,根据一定的规则映射到字符下标,然后添加到text的末尾就行了

每遍历完一个加上换行符“\n”

获取图片某个坐标的灰度值使用img.at<uchar>(x,y)

然后使用cout 输出字符串text就可以看到效果了。 

五、保存为txt文件

进行文件的读写,自然要包含头文件<fstream> 

ofstream outfile("string_picture.txt", ios::trunc);
if (outfile.good())
{
    outfile << text << endl;
    outfile.close();
}

直接使用<<就可以进行文件的写入了,如果对文件操作还不明白的可以去看一下c++中文件操作的部分

可能有些人在记事本的上的效果不明显,就要手动改一下字体设置,我当前的是楷体,小四,效果还是比较好的。 

六、总结

教程到这里就已经完成了,可以看到将图片转化为字符串还是非常简单的,稍微介绍几个所需的函数相信你也可以自己完成。

现在你可以进一步思考一下,能否将视频转为字符动画呢?

视频是由一帧一帧的图片组成的,如果使用一个循环将每一帧图片都转化为字符画,不就完成了码?自己动手思考一下吧。 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值