如果你想找的是“文字识别”,可以看看QT使用PaddleOCR文字识别是不是你想要的
环境
Windows7
Qt Creator 4.5.1 (MSVC2017_64)
Qt 5.10.1
效果图
源码下载
可以从github imgtotext下载代码
部分代码及原理
距离第一次看到这种“图片”怕是有年头了,最近突然想自己实现一个试试,应该说这个程序的原理和代码都不复杂,不过想要较高的运行速度或者处理视频的话可能要借助其他图形处理库并花点心思优化。
用各种语言和工具写了类似程序的人估计都不少了,毕竟网络上时有遇见,而且感觉有经验的人实现这个也就是随手的事,然而其他想知道是如何实现的人就不是很容易找到答案了,换了好几种我认为可以描述这个效果的短语,发现都有描述相近但更受关注的问题,比如搜“图片转文字”的结果基本都是“文字识别”相关的……
一句话概括原理的话,就是用文字来代替图片中的像素点,文字笔画比较稀疏的文字用来表示较浅的颜色,较密的则用来表示深色即可。
剩下的要解决的问题就是找到一种工具可以操作图片的像素并考虑如何进行具体的操作了。
QT的QImage类即可完成上述的任务。
std::vector<QString> textPixel;
textPixel.push_back(QString::fromLocal8Bit("一"));//8个汉字代表8种颜色
textPixel.push_back(QString::fromLocal8Bit("乙"));//从上到下由浅入深
textPixel.push_back(QString::fromLocal8Bit("大"));//使用更多的汉字未必能获得更好的效果
textPixel.push_back(QString::fromLocal8Bit("丙"));//一是因为这种图能表示的像素数量本身就很有限
textPixel.push_back(QString::fromLocal8Bit("交"));//二是汉字的疏密程度也不是很好分级,就难以对应更多的颜色
textPixel.push_back(QString::fromLocal8Bit("羽"));
textPixel.push_back(QString::fromLocal8Bit("拜"));
textPixel.push_back(QString::fromLocal8Bit("慧"));//fromLocal8Bit是为了正确的显示汉字
QString imgPath=QFileDialog::getOpenFileName(this,"Choose Image","","Image File(*.png *.jpg *.bmp)");
if(imgPath.size()==0)
{
return;
}
ui->textBrowser->clear();
QImage q(imgPath);
m_label->resize(ui->widget->size());
m_label->setPixmap(QPixmap::fromImage(q.scaled(m_label->size(),Qt::KeepAspectRatio)));
m_label->show();
q=q.convertToFormat(QImage::Format_Grayscale8);//将图片转换为黑白的
q=q.scaledToWidth(pix);//调整图片大小,使水平方向的像素点为pix个
q.invertPixels();//反置图片颜色,这步可以省略
//如果省略,越亮的像素点颜色数值越大,后面替换成文字的时候就得绕个弯
for(int i=0;i<q.height();++i)
{
for(int j=0;j<q.width();++j)
{
//逐一扫描图片中的像素点,黑白图片的颜色由0-255的整形数字表示
//我们一共使用了8个汉字,那么就将颜色值除以32将其分成八组即可,这里可以使用哈希表优化
ui->textBrowser->insertPlainText(textPixel[qRed(q.pixel(j,i))/32]);
}
ui->textBrowser->insertPlainText("\n");
}
代码中有汉字经常带来问题……如果你编译时出现“常量中含有换行符”的错误,可以如下图设置,或者使用英文等字符替换像素。
这个程序没做什么优化,虽然我设置的像素区间比较大(5-1080),但当你每行使用较多像素点时(大概是200以上?毕竟O(N2)…),会非常耗时,程序会卡住很长时间,慎用。