【瞎折腾/opencv】用记事本打开视频(字符代替像素)

2023-12-24 07:10

本文主要是介绍【瞎折腾/opencv】用记事本打开视频(字符代替像素),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 说在前面
  • Theory
  • SourceCode
  • Result

说在前面

  • opencv版本:4.0.1
  • 操作系统:win10
  • vs版本:2017
  • 其他说明:瞎折腾系列第一期,目前实现的效果并不是很好
  • 基础:【opencv/core module】(二)How to scan images, lookup tables and time measurement with OpenCV
    【opencv/videoio module】(一)Video Input with OpenCV and similarity measurement
    【opencv/videoio module】(二)Creating a video with OpenCV

Theory

  • 原理其实很简单
  1. 捕捉视频一帧,转为灰度图
  2. 降低颜色空间的大小
  3. 对每一个位置的像素用一个字符代替,字符所占的比例逐渐增大(例如 . ; + # @这样,相当于颜色逐渐加深)
  4. 最后,将转化后的由字符形成这一帧保存起来
  • 存在的问题
  1. 用哪些字符替代?

  2. 用哪种方式保存字符帧?

    这两问题我觉得有些联系,我在实验中用的是putText()函数,将字符直接输出到Mat上,然后使用VideoWriter写入到视频文件中,这样便于视频的生成;但是putText这个函数用的时候有些偏差,有些字符所占的宽度不是固定的,会导致最终结果emmm(っ °Д °;)っ
    在这里插入图片描述
    另一种保存方式,直接输出到文本文件中,这样就没有putText的问题,但是如何将其转换成视频?难道一帧一帧的截图 (不嫌麻烦可以一试,代码也有) ?(而且ascii码的话长宽是不等的)emmmm┗|`O′|┛
    在这里插入图片描述

SourceCode

主要是putText函数

void cv::putText 
(
InputOutputArray img, //输入到img上
const String & text, //要显示的字符
Point org, //要显示的位置(像素)
int fontFace, //字体类型
double fontScale, //字体缩放
Scalar color, //字体颜色
int thickness = 1, //字体粗细
int lineType = LINE_8, //线条类型
bool bottomLeftOrigin = false //是否将text的左下角作为起始位置,否的话左上角
)

字体类型(实验中用的是1,也就是FONT_HERSHEY_PLAIN,貌似最小的)

name含义
FONT_HERSHEY_SIMPLEXnormal size sans-serif font
FONT_HERSHEY_PLAINsmall size sans-serif font
FONT_HERSHEY_DUPLEXnormal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX)
FONT_HERSHEY_COMPLEXnormal size serif font
FONT_HERSHEY_TRIPLEXnormal size serif font (more complex than FONT_HERSHEY_COMPLEX)
FONT_HERSHEY_COMPLEX_SMALLsmaller version of FONT_HERSHEY_COMPLEX
FONT_HERSHEY_SCRIPT_SIMPLEXhand-writing style font
FONT_HERSHEY_SCRIPT_COMPLEXmore complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX
FONT_ITALICflag for italic font

线条类型(用的0,填充)

name含义
FILLED
LINE_44-connected line
LINE_88-connected line
LINE_AAantialiased line

最后一个参数,在确定Point org后,相当于下面哪一个点(左边俩黑色)作为org
在这里插入图片描述

#include <iostream> // for standard I/O
#include <string>   // for strings
#include <opencv2/core.hpp>     // Basic OpenCV structures (cv::Mat)
#include <opencv2/videoio.hpp>  // Video write
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace std;
using namespace cv;int CNT = 0;void ProcessText(Mat& I)
{CV_Assert(I.depth() == CV_8U && I.channels() == 1);string txt_name = "test_" + to_string(CNT) + ".txt";ofstream out(txt_name);for (int i = 15; i < I.rows - 10; ++i){char text[240] = { 0 };for (int j = 20; j < I.cols - 25; ++j){if (I.at<uchar>(i, j) < 25)text[j - 20] = '-';else if (I.at<uchar>(i, j) < 50)text[j - 20] = '-';else if (I.at<uchar>(i, j) < 75)text[j - 20] = '<';else if (I.at<uchar>(i, j) < 100)text[j - 20] = '>';else if (I.at<uchar>(i, j) < 125)text[j - 20] = '+';else if (I.at<uchar>(i, j) < 150)text[j - 20] = '+';else if (I.at<uchar>(i, j) < 175)text[j - 20] = '&';else if (I.at<uchar>(i, j) < 200)text[j - 20] = '&';else if (I.at<uchar>(i, j) < 225)text[j - 20] = '%';else if (I.at<uchar>(i, j) < 250)text[j - 20] = '#';elsetext[j - 20] = '@';}out << text << endl;}CNT++;out.close();
}int ggg = 0;void Process(Mat& I, Mat& Out)
{// accept only char type matricesCV_Assert(I.depth() == CV_8U && I.channels() == 1);for (int i = 15; i < I.rows - 10; ++i){char text[240] = { 0 };for (int j = 20; j < I.cols - 25; ++j){if (I.at<uchar>(i, j) < 25)text[j - 20] = '-';else if (I.at<uchar>(i, j) < 50)text[j - 20] = '-';else if (I.at<uchar>(i, j) < 75)text[j - 20] = '<';else if (I.at<uchar>(i, j) < 100)text[j - 20] = '>';else if (I.at<uchar>(i, j) < 125)text[j - 20] = '+';else if (I.at<uchar>(i, j) < 150)text[j - 20] = '+';else if (I.at<uchar>(i, j) < 175)text[j - 20] = '&';else if (I.at<uchar>(i, j) < 200)text[j - 20] = '&';else if (I.at<uchar>(i, j) < 225)text[j - 20] = '%';else if (I.at<uchar>(i, j) < 250)text[j - 20] = '#';elsetext[j - 20] = '@';}putText(Out, text, Point(0, (i - 14) * 10), 1, 1, Scalar(255), 1, 1);if (ggg == 0)cout << text << endl;}ggg = 1;}int main()
{const string source = "1.mp4";           // the source file nameconst string NAME = "test.avi";   // Form the new name with containerint divideWith = 25;uchar table[256];for (int i = 0; i < 256; ++i)table[i] = (uchar)(divideWith * (i / divideWith));Mat lookUpTable(1, 256, CV_8U);uchar* p = lookUpTable.ptr();for (int i = 0; i < 256; ++i)p[i] = table[i];VideoCapture inputVideo(source);              // Open inputif (!inputVideo.isOpened()){cout << "Could not open the input video: " << source << endl;return -1;}VideoWriter outputVideo(NAME, VideoWriter::fourcc('M', 'J', 'P', 'G'),inputVideo.get(CAP_PROP_FPS), Size(960*2, 540*2), true);if (!outputVideo.isOpened()){cout << "Could not open the output video for write: " << NAME << endl;return -1;}Mat src;while (true){inputVideo >> src;              // readif (src.empty()) break;         // check if at endpyrDown(src, src, Size(src.cols / 2, src.rows / 2));//缩放pyrDown(src, src, Size(src.cols / 2, src.rows / 2));//缩放pyrDown(src, src, Size(src.cols / 2, src.rows / 2));//缩放cvtColor(src, src, COLOR_BGR2GRAY);//转为灰度图LUT(src, lookUpTable, src);//降低颜色空间imshow("src", src);Mat res(Size(1920, 1080),CV_8UC1);//用于保存结果Process(src, res);//处理//pyrDown(res, res, Size(960, 540));//缩放cvtColor(res, res, COLOR_GRAY2BGR);//转化成BGR,VideoWriter的问题imshow("test", res);outputVideo << res;//写入//ProcessText(src);waitKey(15);}return 0;
}

Result

  • 上面原图,下面结果,都是gif

在这里插入图片描述
在这里插入图片描述


END

这篇关于【瞎折腾/opencv】用记事本打开视频(字符代替像素)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/530961

相关文章

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

Python视频处理库VidGear使用小结

《Python视频处理库VidGear使用小结》VidGear是一个高性能的Python视频处理库,本文主要介绍了Python视频处理库VidGear使用小结,文中通过示例代码介绍的非常详细,对大家的... 目录一、VidGear的安装二、VidGear的主要功能三、VidGear的使用示例四、VidGea

opencv实现像素统计的示例代码

《opencv实现像素统计的示例代码》本文介绍了OpenCV中统计图像像素信息的常用方法和函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 统计像素值的基本信息2. 统计像素值的直方图3. 统计像素值的总和4. 统计非零像素的数量

如何提高Redis服务器的最大打开文件数限制

《如何提高Redis服务器的最大打开文件数限制》文章讨论了如何提高Redis服务器的最大打开文件数限制,以支持高并发服务,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录如何提高Redis服务器的最大打开文件数限制问题诊断解决步骤1. 修改系统级别的限制2. 为Redis进程特别设置限制

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

opencv 滚动条

参数介绍:createTrackbar( trackbarname , "hello" , &alpha_slider ,alpha_max ,  on_trackbar )  ;在标签中显示的文字(提示滑动条的用途) TrackbarName创建的滑动条要放置窗体的名字 “hello”滑动条的取值范围从 0 到 alpha_max (最小值只能为 zero).滑动后的值存放在