热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

图像的ASCII码显示v1—ASCIIart--justforfun

这两天闲着没事,觉得将图像内容用ASCII码显示出来挺有意思的,就自己尝试着写了写,到网上一搜才知道原来这东西还是一门艺术-ASCIIart!!咱也跟艺术沾边了O(∩_∩)

       这两天闲着没事,觉得将图像内容用ASCII码显示出来挺有意思的,就自己尝试着写了写,到网上一搜才知道原来这东西还是一门艺术-ASCII art!!大笑

咱也跟艺术沾边了O(∩_∩)O哈哈哈~

      闲话少说,切入正题,将图像内容用ASCII码显示出来主要就是用不同的字符表示灰度,以此来区分不同的灰度值达到将内容可视化的目的,这个道理很简单,实现起来其实也不难,如果是直接输入到控制台或者txt文件的则比较简单,主要是需要设置一下字体的宽高,最好是正方形的,否则看起来会比较别扭。下面一个是将lena缩放到100*100之后在控制台窗口直接显示的截图,采用的字符是标点,字体设置的宽高相等为8*8:

        但是这种方式无法保存成图像(当然可以截图,不过那多费劲!),所以就研究了一下如何将字符直接写到图像上,这样保存图像就可以了。这时关键的问题就是如何将字符写到图像上,并且尽量让字符的宽高相等,这样看起来才不会觉得图像被挤过了⊙﹏⊙b汗!

        还是用OpenCV来将字符写到图像上,使用putText函数,不过OpenCV中的字体好像不能设置为等宽高,没办法,就取了折中的方法,将用来代替灰度的所有字符的宽度和高度取了个平均作为字符宽高,这样就将原图像中的一个像素替换为这样一个字符,而且还设置了几个选项:可以选择标点,字母或者数字来代替灰度,并且可以选择输出二值,灰度或者彩色ascii图像-----文中只使用了8个灰度级,即将整幅图像量化为了8个灰度级,这样的缺点就是对灰度分布比较集中的图像失真比较大,可以先对图像进行灰度均衡化处理之后再转换,这里没有考虑这些,下面是主要的函数代码。

char ascii_code_symbol[CODE_SIZE-7] = {'#','&','$','*','+',';','.',' ',0};
char ascii_code_letter[CODE_SIZE-7] = {'m','n','e','f','t','l','i',' ',0};
char ascii_code_number[CODE_SIZE-7] = {'8','9','5','3','2','7','1',' ',0};
char *ascii_code_8[3] = { ascii_code_symbol, ascii_code_letter, ascii_code_number};


//check the input image size and return a defined size,
// that's the max one of width and height is not bigger than 100;
cv::Size get_board_size(Mat &image)
{
	if(image.empty())
		return Size(0,0);

	int f = 0;
	float big=(float)image.rows, smal=(float)image.cols;
	if(image.cols>image.rows)
	{
		f = 1;
		big = float(image.cols);
		smal = float(image.rows);
	}
	
	cv::Size board_size;
	if(big <= 100.f)
	{
		board_size = cv::Size(image.cols, image.rows);
	}
	else
	{
		board_size = cv::Size(int(f==1?100:(100*image.cols/big)), int(f==1?(100*image.rows/big):100));
	}
	return board_size;
}

//get the char code step
int get_char_size(const string &asciiStr)
{
	//init font
	int fOntFace= FONT_HERSHEY_PLAIN;
	double fOntScale= 0.5;
	int thickness = 1;

	//max_size is the max of all the char code width and height,
	//or return the average size of all the char code width and height;
	int max_size = 0;
	int total_size = 0;
	for (size_t i=0; i2 || code_type<0)
		return Mat();

	//if input is a gray image, set color_type to gray;
	if(image.channels()==1&&code_type==2)
		color_type = 1;
	
	//create the output image
	int char_size = get_char_size(ascii_code_8[code_type]);
	cv::Size board_size = get_board_size(image);
	Mat out_image(char_size*board_size.height, char_size*board_size.width, CV_8UC3,Scalar::all(0));
	
	//resize the input image to defined size;
	Mat resized_image;
	resize(image, resized_image, board_size);
	Mat gray_image;
	if(resized_image.channels() == 3)
		cvtColor(resized_image, gray_image, COLOR_BGR2GRAY);
	else
		gray_image = resized_image;

	//font init
	int fOntFace= FONT_HERSHEY_PLAIN;
	double fOntScale= 0.5;
	int thickness = 1;

	//print char code to the output image
	for (int i=0; i(i);
		uchar *ptr_gray = gray_image.ptr(i);
		for (int j=0; j>5)]);
			
			//colored or not
			if (color_type==0) 
			{
				putText(out_image, text, textOrg, fontFace, fontScale, Scalar::all(255));
			}
			else if(color_type==1)
			{
				putText(out_image, text, textOrg, fontFace, fontScale, Scalar::all(pix_gray));
			}
			else
			{
				putText(out_image, text, textOrg, fontFace, fontScale, Scalar(ptr_bgr[3*j],ptr_bgr[3*j+1],ptr_bgr[3*j+2]));
			}
		}
	}

	return out_image;
}


下面是采用数字的ascii字符的彩色和灰度以及二值lena图像,【对lena图像来说数字的看起来比较好,其他两种效果不如数字的】

可以看出效果还是比较好的,O(∩_∩)O,

当然这里只是简单的将像素进行了替换是基于灰度的,更高级的可以有基于结构的,如边缘,生成更加简练的内容表达,以后有时间再研究研究~~


推荐阅读
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
author-avatar
海边遗忘的时光_958
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有