用python和opencv画字符画

一、 思路

其实这种字符画如果要求不高,真的挺简单的

1、准备好字符集
2、先将图片变成灰度图
3、将灰度图里面的不同灰度转化为不同字符
4、保存


二、代码

import cv2
import numpy as np
#字符画画笔(像素由大到小)
arr=["W","N","D","t","x","i","+","-","."," "]

#这个是为了求图片刚好能在电脑上显示的最大倍数
def change_rate(h,w):
    rate,hh,ww=1,h,w
    while hh>680 or ww>1600:
        rate-=0.005
        hh=rate*h
        ww=rate*w
    return rate

img =cv2.imread("cv22.jpg")

#获取像素大小并缩小过大的图片
h=np.size(img,0)
w=np.size(img,1)
rate=change_rate(h,w)
imgg=cv2.resize(img,(0,0),fx=rate,fy=rate)
cv2.imshow("img",imgg)
cv2.waitKey(5)
h=np.size(imgg,0)
w=np.size(imgg,1)

#转换为灰度图
gray=cv2.cvtColor(imgg,cv2.COLOR_BGR2GRAY)

#建立画板
res=np.ndarray([h,w])

#建立图画
for i in range(0,h,5):
    for j in range(0,w,5):
        t=arr[gray[i,j]//26]
        cv2.putText(res,t,(j,i),cv2.FONT_HERSHEY_SIMPLEX,0.1,color=(255,255,255))

cv2.imshow("res",res)
cv2.imwrite("D:cv22_2.jpg",res)

cv2.waitKey()



三、注意点

  1. 有的图片过大,打开时早就占满了整个电脑屏幕,因此要先将图片缩小。
  2. 为了要让画面整洁,字符集里面最好要有空格字符" "。
  3. 保存的时候记得,路径里面不能有中文,然后我一开始是只有名称"tree_1.jpg",结果找不到,然后在前面加了详细路径,但因为有中文也不行,最后是把中文删掉后,变成图上这种"D:three_1.jpg",就可以了。

四、成果

在这里插入图片描述


五、改进

1.改为白底黑字

只需要改两个地方

  • 一个是建立白色的画板
#建立画板
res=np.ndarray([h,w])

改为

#建立画板
res = np.ones((h, w, 3), dtype=np.uint8) * 255
  • 另一个就是把输出字符改为黑色
cv2.putText(res,t,(j,i),cv2.FONT_HERSHEY_SIMPLEX,0.1,color=(0,0,0))
得到例图如下:

在这里插入图片描述

2.彩色字符串

(1).了解putText

cv::putText的原型:

	void cv::putText(
		cv::Mat& img, // 待绘制的图像
		const string& text, // 待绘制的文字,具体为字符串类型
		cv::Point origin, // 文本框的左上角的位置
		int fontFace, // 字体 (常见的如  cv::FONT_HERSHEY_PLAIN),
		double fontScale, // 尺寸因子,值越大文字越大
		cv::Scalar color, // 线条的颜色(RGB)
		int thickness = 1, // 线条粗细宽度
		int lineType = 8, // 线型(4邻域或8邻域,默认8邻域)
		bool bottomLeftOrigin = false // 看图像的坐标原点是否位于左下角,值为true,图像原点位于左下角,值为false,图像原点位于左上角
	);
(2). 获取颜色RGB

然后知道我们的目的是为了得到每个像素的字符串对应的颜色

for i in range(0,h,5):
    for j in range(0,w,5):
        pixel=imgg[i,j]#获取颜色
        colors= (int (pixel[0]),int(pixel[1]),int(pixel[2]))
        t=arr[gray[i,j]//26]
        if gray[i,j]>210:
            t=" "
        cv2.putText(res,t,(j,i),cv2.FONT_HERSHEY_SIMPLEX,0.1,color=colors)#更改颜色
(3).知识点(原理)

这里的关键点在于pixel=imgg[i,j]语句获取了图像 imgg在 (i, j) 坐标位置的像素值。

OpenCV 读取的图像是一个三维的 NumPy 数组,表示图像的像素矩阵。每个像素点都由三个值组成,分别表示蓝色、绿色和红色通道的强度,通常按照 BGR(蓝-绿-红)的顺序排列。

接下来的 colors = (int(pixel[0]), int(pixel[1]), int(pixel[2]))将这个像素点的 BGR 强度值转化为一个颜色元组。这个颜色元组可以直接用于 cv2.putText 函数,该函数的 color 参数接受一个颜色元组,用于指定字符的颜色。

所以,这段代码的逻辑是:

1.pixel=imgg[i,j]获取原始图像在 (i, j) 处的像素值。
2.colors = (int(pixel[0]), int(pixel[1]), int(pixel[2]))将 BGR 强度值转化为颜色元组。
3.cv2.putText(res, t, (j, i), cv2.FONT_HERSHEY_SIMPLEX, 0.1, color=colors) 将字符 t 以指定的颜色绘制到字符图 res 上。

这样,每个字符在字符图上的颜色都由对应位置原始图像的像素值决定。cv2.imread 读取的图像是按照 BGR 通道排列的,所以这里使用 BGR 强度值来构造颜色元组。

(4).完整代码

import cv2
import numpy as np
#字符画画笔(像素由大到小)
arr=["W","N","D","t","x","i","+","-","."," "]

#这个是为了求图片刚好能在电脑上显示的最大倍数
def change_rate(h,w):
    rate,hh,ww=1,h,w
    while hh>680 or ww>1600:
        rate-=0.005
        hh=rate*h
        ww=rate*w
    return rate

img =cv2.imread("work.jpg")

#获取像素大小并缩小过大的图片
h=np.size(img,0)
w=np.size(img,1)
rate=change_rate(h,w)
imgg=cv2.resize(img,(0,0),fx=rate,fy=rate)
cv2.imshow("img",imgg)
cv2.waitKey(5)
h=np.size(imgg,0)
w=np.size(imgg,1)

#转换为灰度图
gray=cv2.cvtColor(imgg,cv2.COLOR_BGR2GRAY)

#建立画板
res = np.ones((h, w, 3), dtype=np.uint8) * 255



#建立图画
for i in range(0,h,5):
    for j in range(0,w,5):
        pixel=imgg[i,j]#获取颜色
        colors= (int (pixel[0]),int(pixel[1]),int(pixel[2]))
        t=arr[gray[i,j]//26]
        if gray[i,j]>210:
            t=" "
        cv2.putText(res,t,(j,i),cv2.FONT_HERSHEY_SIMPLEX,0.1,color=colors)#更改颜色


cv2.imshow("res",res)
cv2.imwrite("D:work_2.jpg",res)

cv2.waitKey()



(5).例图

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

  • 28
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值