【python学习笔记】番外篇-1.openCV+文件操作

本文记录了一次使用Python和OpenCV将图像转换为文本再转回图像的过程,涉及图像读取、文本写入、正则表达式处理和numpy矩阵运算。在实践中遇到将文本文件还原为图像的难点,通过正则表达式找到了解决方案,最终成功完成图像的加密转换。
摘要由CSDN通过智能技术生成

碎碎念

国庆假期过去了,我快乐的自由时间又要被该死的学校的课打断了。入秋天气渐凉,唯一找到的下午晒太阳学习的地方也不能去了。晚上回到宿舍打算看看正则表达式的教程,半路也被新番吸引。。。学习路上真是坎坷
不过听到一个有趣的需求,大概是将图像转换成文本,然后把文本在转为图像。背景是图像加密。这让我想起之前有个新闻提到泄露商业秘密的那个大佬,将图片写在普通文件里的操作。
在和同学吹了一阵牛逼之后,想着还是自己试着写写吧,就用刚刚学的python和包就可以解决呢。

需求

将图片文件转换为文本文件,再将文本文件转换为图像文件。

工具

使用语言选择python,需要用到的包有openCV,re(正则表达式包),numpy(矩阵运算包)

思路

图片文件无非是一个巨大的多位数组,把这些数组按照行列挨个读出,转换为字符串写入文件即可。反之在将文本文件读入,转换成数组按照图片保存不就对了吗。看似很简单嘛。

实现

首先,根据之前的学习,可以使用cv2.read()函数将图片放到变量中,再使用open()函数创建一个文本文件。这里为了方便就先使用灰度图像书写逻辑。

import cv2
img = cv2.imread("/Users/wch/Desktop/changed.jpeg",0)
f = open("image",'w')

然后呢,我们按照存有图片的变量img的大小进行遍历像素(在这里,img是一个numpy.array对象,和二维列表还有所不同。不过这时候我还没有意识到,只是自以为是的继续做咯。)。这里用到一个 图片对象的 .shape() 方法,读出图片的宽和长,返回一个列表。由于是一个像素一个像素写入文件,在每个像素后面添加“,”在每一列之间添加换行。

for x in range(img.shape[0]):
	for y in range(img.shape[1]):
		f.write(str(img[x][y])+',')
	f.write("\n")
f.close()

到这里,第一个目标实现啦,我们输出一下试试:
存有图像像素灰度数据的文本文件!
效果还不错呢。到这一步,加密处理还是怎样都随意咯。但是真正的困难是还原图像。第一步就是将文本文件读入变量了,这很容易的。(熟练的写下一下代码,注释部分会解释哦)

#import cv2
#import re
#import numpy as np
f = open("/Users/wch/Desktop/image",'r')

走到这里,傻眼了。忽然意识到无论我怎么读取这个文件,都需要进行字符串分割,还要转换成整形,而且还要注意行列。也许大佬不以为意,但是我是学C语言出身的,到这里以我的思路就是使用文件指针顺序读入。使用格式化读取可以方便的处理字符串,文件指针也会自动顺序读取。可是python该怎么做呢?如果手动读入每个字符,转换成整形还需要进行位处理!没个像素值的位数还不同!这种面向过程的思考方式着实害我不浅。
既然面向对象,我怎样才能直接处理这串超长的文件呢。。。正则表达式啊!而且正则表达式的包还能自动将匹配结果转换成列表呢!列表不就是图像了吗!
走到这里,我频繁试错长达20分钟。看来,思想还需要改进啊。
导入re包,使用正则表达式进行匹配。

prog = re.compile('(\d+),')
 #\d表示匹配数字,+表示多次匹配,‘,’表示匹配字符是‘,’结尾,
 #()表示匹配完成后只取括号内的字符。
ones = f.readlines()	#读入文件,按行返回二维列表
end = []		#创建空数组,存储图像数据
for one in ones :
	twos = re.findall(prog,one)	#re方法,匹配每一行字符串中所有符合条件的值,返回列表
	pixel = []		#创建空数组,用来存储行像素
	for two in twos:
		pixel.append(int(two))		#将单个像素信息写入行列表
	end.append(pixel)				#将单行列表写入图像列表

到这里,文件的转换已经大功告成,虽然我相信python一定有更简洁的表达方式,但是这个写法,起码是学到现在我可以写出的比较短的代码了呢。
最后就是把变量end用opencv保存了,看看是否能成功把!

cv2.imwrite("/Users/wch/Desktop/ttt.jpeg",end)

# Traceback (most recent call last):
#   File "/Users/wch/Desktop/ttt2.py", line 17, in <module>
#     cv2.imwrite("/Users/wch/Desktop/ttt.jpeg",end)
# TypeError: img is not a numpy array, neither a scalar

类型错误。。。不过这个numpy array像是在哪里见过呢。经过查找,发现他是矩阵的形式,所以呢,导入numpy包,使用 .array()将二维数组转换为二维矩阵。

cv2.imwrite("/Users/wch/Desktop/ttt.jpeg",np.array(end))

成功输出图像!
转换成功 !

总结

这次的尝试真的受益匪浅。再次验证了学习语言一定要动手这条原则。当你尝试去写的时候才发现,那些脑袋里的想法有多么天真。多写程序,多尝试不同的思考模式,最后才能成为一个真正的“创作型程序猿”。所以,看完之后不妨自己试试写一个彩色图像的处理的,或者创建一个有交互的小程序吧!

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值