如何用python将很多图片组合一张把文字拼成特定形状状的图片

python 判断图片相似度一个十分简单的示例 - 开源中国社区
当前访客身份:游客 [
当前位置:
发布于 日 21时,
python&判断图片相似度一个十分简单的示例,只是个例子,精度可能不是很高。主要介绍一下原理:先将图片转为&12x12像素的灰度图片--获取图片平均灰度--遍历图片内部10x10像素(去掉周围1像素)--比较每一个像素与平均值大小--如果大则字符串加1不然加0(这里我选用字符串保存,其实方法很多的)--接下去就是遍历文件夹中图片了,比较相似度,返回相似度了
代码片段(1)
1.&[代码][Python]代码&&&&
from PIL import Image
#import hashlib
def getGray(image_file):
for h in range(0,
image_file.size[1]):#h
for w in range(0, image_file.size[0]):#w
tmpls.append( image_file.getpixel((w,h))
return tmpls
def getAvg(ls):#获取平均灰度值
return sum(ls)/len(ls)
def getMH(a,b):#比较100个字符有几个字符相同
for i in range(0,len(a)):
if a[i]==b[i]:
dist=dist+1
return dist
def getImgHash(fne):
image_file = Image.open(fne) # 打开
image_file=image_file.resize((12, 12))#重置图片大小我12px X 12px
image_file=image_file.convert("L")#转256灰度图
Grayls=getGray(image_file)#灰度集合
avg=getAvg(Grayls)#灰度平均值
bitls=''#接收获取0或1
#除去变宽1px遍历像素
for h in range(1,
image_file.size[1]-1):#h
for w in range(1, image_file.size[0]-1):#w
if image_file.getpixel((w,h))&=avg:#像素的值比较平均值 大于记为1 小于记为0
bitls=bitls+'1'
bitls=bitls+'0'
return bitls
m2 = hashlib.md5()
m2.update(bitls)
print m2.hexdigest(),bitls
return m2.hexdigest()
a=getImgHash("./Test/测试图片.jpg")#图片地址自行替换
files = os.listdir("./Test")#图片文件夹地址自行替换
for file in files:
b=getImgHash("./Test/"+str(file))
compare=getMH(a,b)
print file,u'相似度',str(compare)+'%'
开源中国-程序员在线工具:
相关的代码(1176)
0回/3547阅
0回/1177阅
0回/1051阅
学习学习,虽然看不太懂,大神的注释标注得很清楚
2楼:宝具滑 发表于
引用来自“努力的小明”的评论学习学习,虽然看不太懂,大神的注释标注得很清楚不是什么大神,我 只是是业余的!?(? ? ??)
开源从代码分享开始
宝具滑的其它代码形态学处理,除了最基本的膨胀、腐蚀、开/闭运算、黑/白帽处理外,还有一些更高级的运用,如凸包,连通区域标记,删除小块区域等。
凸包是指一个凸多边形,这个凸多边形将图片中所有的白色像素点都包含在内。
skimage.morphology.convex_hull_image(image)
输入为二值图像,输出一个逻辑二值图像。在凸包内的点为True, 否则为False
import matplotlib.pyplot as plt
from skimage import data,color,morphology
#生成二值测试图像
img=color.rgb2gray(data.horse())
img=(img&0.5)*1
chull = morphology.convex_hull_image(img)
fig, axes = plt.subplots(1,2,figsize=(8,8))
ax0, ax1= axes.ravel()
ax0.imshow(img,plt.cm.gray)
ax0.set_title('original image')
ax1.imshow(chull,plt.cm.gray)
ax1.set_title('convex_hull image')
convex_hull_image()是将图片中的所有目标看作一个整体,因此计算出来只有一个最小凸多边形。如果图中有多个目标物体,每一个物体需要计算一个最小凸多边形,则需要使用convex_hull_object()函数。
函数格式:skimage.morphology.convex_hull_object(image,&neighbors=8)
输入参数image是一个二值图像,neighbors表示是采用4连通还是8连通,默认为8连通。
import matplotlib.pyplot as plt
from skimage import data,color,morphology,feature
#生成二值测试图像
img=color.rgb2gray(data.coins())
#检测canny边缘,得到二值图片
edgs=feature.canny(img, sigma=3, low_threshold=10, high_threshold=50)
chull = morphology.convex_hull_object(edgs)
fig, axes = plt.subplots(1,2,figsize=(8,8))
ax0, ax1= axes.ravel()
ax0.imshow(edgs,plt.cm.gray)
ax0.set_title('many objects')
ax1.imshow(chull,plt.cm.gray)
ax1.set_title('convex_hull image')
plt.show()
2、连通区域标记
在二值图像中,如果两个像素点相邻且值相同(同为0或同为1),那么就认为这两个像素点在一个相互连通的区域内。而同一个连通区域的所有像素点,都用同一个数值来进行标记,这个过程就叫连通区域标记。在判断两个像素是否相邻时,我们通常采用4连通或8连通判断。在图像中,最小的单位是像素,每个像素周围有8个邻接像素,常见的邻接关系有2种:4邻接与8邻接。4邻接一共4个点,即上下左右,如下左图所示。8邻接的点一共有8个,包括了对角线位置的点,如下右图所示。
在skimage包中,我们采用measure子模块下的label()函数来实现连通区域标记。
函数格式:
skimage.measure.label(image,connectivity=None)
参数中的image表示需要处理的二值图像,connectivity表示连接的模式,1代表4邻接,2代表8邻接。
输出一个标记数组(labels), 从0开始标记。
import numpy as np
import scipy.ndimage as ndi
from skimage import measure,color
import matplotlib.pyplot as plt
#编写一个函数来生成原始二值图像
def microstructure(l=256):
x, y = np.ogrid[0:l, 0:l]
mask = np.zeros((l, l))
generator = np.random.RandomState(1)
#随机数种子
points = l * generator.rand(2, n**2)
mask[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1
mask = ndi.gaussian_filter(mask, sigma=l/(4.*n)) #高斯滤波
return mask & mask.mean()
data = microstructure(l=128)*1 #生成测试图片
labels=measure.label(data,connectivity=2)
#8连通区域标记
dst=color.label2rgb(labels)
#根据不同的标记显示不同的颜色
print('regions number:',labels.max()+1)
#显示连通区域块数(从0开始标记)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
ax1.imshow(data, plt.cm.gray, interpolation='nearest')
ax1.axis('off')
ax2.imshow(dst,interpolation='nearest')
ax2.axis('off')
fig.tight_layout()
plt.show()
在代码中,有些地方乘以1,则可以将bool数组快速地转换为int数组。
结果如图:有10个连通的区域,标记为0-9
如果想分别对每一个连通区域进行操作,比如计算面积、外接矩形、凸包面积等,则需要调用measure子模块的regionprops()函数。该函数格式为:
skimage.measure.regionprops(label_image)
返回所有连通区块的属性列表,常用的属性列表如下表:
区域内像素点总数
边界外接框(min_row,&min_col,&max_row,&max_col)
convex_area
凸包内像素点总数
convex_image
和边界外接框同大小的凸包  
区域内像素点坐标
Eccentricity&
equivalent_diameter&
和区域面积相同的圆的直径
euler_number
区域欧拉数
区域面积和边界外接框面积的比率
filled_area
区域和外接框之间填充的像素点总数
perimeter&
3、删除小块区域
有些时候,我们只需要一些大块区域,那些零散的、小块的区域,我们就需要删除掉,则可以使用morphology子模块的remove_small_objects()函数。
函数格式:skimage.morphology.remove_small_objects(ar,&min_size=64,&connectivity=1,&in_place=False)
ar: 待操作的bool型数组。
min_size: 最小连通区域尺寸,小于该尺寸的都将被删除。默认为64.
connectivity: 邻接模式,1表示4邻接,2表示8邻接
in_place: bool型值,如果为True,表示直接在输入图像中删除小块区域,否则进行复制后再删除。默认为False.
返回删除了小块区域的二值图像。
import numpy as np
import scipy.ndimage as ndi
from skimage import morphology
import matplotlib.pyplot as plt
#编写一个函数来生成原始二值图像
def microstructure(l=256):
x, y = np.ogrid[0:l, 0:l]
mask = np.zeros((l, l))
generator = np.random.RandomState(1)
#随机数种子
points = l * generator.rand(2, n**2)
mask[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1
mask = ndi.gaussian_filter(mask, sigma=l/(4.*n)) #高斯滤波
return mask & mask.mean()
data = microstructure(l=128) #生成测试图片
dst=morphology.remove_small_objects(data,min_size=300,connectivity=1)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
ax1.imshow(data, plt.cm.gray, interpolation='nearest')
ax2.imshow(dst,plt.cm.gray,interpolation='nearest')
fig.tight_layout()
plt.show()
在此例中,我们将面积小于300的小块区域删除(由1变为0),结果如下图:
&4、综合示例:阈值分割+闭运算+连通区域标记+删除小区块+分色显示
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from skimage import data,filter,segmentation,measure,morphology,color
#加载并裁剪硬币图片
image = data.coins()[50:-50, 50:-50]
thresh =filter.threshold_otsu(image) #阈值分割
bw =morphology.closing(image & thresh, morphology.square(3)) #闭运算
cleared = bw.copy()
segmentation.clear_border(cleared)
#清除与边界相连的目标物
label_image =measure.label(cleared)
#连通区域标记
borders = np.logical_xor(bw, cleared) #异或
label_image[borders] = -1
image_label_overlay =color.label2rgb(label_image, image=image) #不同标记用不同颜色显示
fig,(ax0,ax1)= plt.subplots(1,2, figsize=(8, 6))
ax0.imshow(cleared,plt.cm.gray)
ax1.imshow(image_label_overlay)
for region in measure.regionprops(label_image): #循环得到每一个连通区域属性集
#忽略小区域
if region.area & 100:
#绘制外包矩形
minr, minc, maxr, maxc = region.bbox
rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
fill=False, edgecolor='red', linewidth=2)
ax1.add_patch(rect)
fig.tight_layout()
plt.show()
阅读(...) 评论()Python(170)
在网上看到python做图像识别的相关文章后,真心感觉python的功能实在太强大,因此将这些文章总结一下,建立一下自己的知识体系。
当然了,图像识别这个话题作为计算机科学的一个分支,不可能就在本文简单几句就说清,所以本文只作基本算法的科普向。
如有错误,请多包涵和多多指教。
参考的文章和图片来源会在底部一一列出。
以及本篇文章所用的代码都会在底下给出github地址。
python用作图像处理的相关库主要有openCV(C++编写,提供了python语言的接口),PIL,但由于PIL很早就停了,所以不支持python3.x,所以建议使用基于PIL的pillow,本文也是在python3.4和pillow的环境下进行实验。
至于opencv,在做人脸识别的时候会用到,但本文不会涉及到,在本专栏的后续中会谈及openCV的人脸识别和基于此的python图片爬虫,有兴趣的朋友可以关注本专栏。
要识别两张相似图像,我们从感性上来谈是怎么样的一个过程?首先我们会区分这两张相片的类型,例如是风景照,还是人物照。风景照中,是沙漠还是海洋,人物照中,两个人是不是都是国字脸,还是瓜子脸(还是倒瓜子脸……哈哈……)。
那么从机器的角度来说也是这样的,先识别图像的特征,然后再相比。
很显然,在没有经过训练的计算机(即建立模型),那么计算机很难区分什么是海洋,什么是沙漠。但是计算机很容易识别到图像的像素值。
因此,在图像识别中,颜色特征是最为常用的。(其余常用的特征还有纹理特征、形状特征和空间关系特征等)
其中又分为
这里先用直方图进行简单讲述。
先借用一下恋花蝶的图片,
从肉眼来看,这两张图片大概也有八成是相似的了。
在python中可以依靠Image对象的histogram()方法获取其直方图数据,但这个方法返回的结果是一个列表,如果想得到下图可视化数据,需要另外使用&matplotlib,这里因为主要介绍算法思路,matplotlib的使用这里不做介绍。
是的,我们可以明显的发现,两张图片的直方图是近似重合的。所以利用直方图判断两张图片的是否相似的方法就是,计算其直方图的重合程度即可。
计算方法如下:
其中gi和si是分别指两条曲线的第i个点。
最后计算得出的结果就是就是其相似程度。
不过,这种方法有一个明显的弱点,就是他是按照颜色的全局分布来看的,无法描述颜色的局部分布和色彩所处的位置。
也就是假如一张图片以蓝色为主,内容是一片蓝天,而另外一张图片也是蓝色为主,但是内容却是妹子穿了蓝色裙子,那么这个算法也很可能认为这两张图片的相似的。
缓解这个弱点有一个方法就是利用Image的crop方法把图片等分,然后再分别计算其相似度,最后综合考虑。
在介绍下面其他判别相似度的方法前,先补充一些概念。第一个就是图像指纹
图像指纹和人的指纹一样,是身份的象征,而图像指纹简单点来讲,就是将图像按照一定的哈希算法,经过运算后得出的一组二进制数字。
说到这里,就可以顺带引出汉明距离的概念了。
假如一组二进制数据为101,另外一组为111,那么显然把第一组的第二位数据0改成1就可以变成第二组数据111,所以两组数据的汉明距离就为1
简单点说,汉明距离就是一组二进制数据变成另一组数据所需的步骤数,显然,这个数值可以衡量两张图片的差异,汉明距离越小,则代表相似度越高。汉明距离为0,即代表两张图片完全一样。
如何计算得到汉明距离,请看下面三种哈希算法
此算法是基于比较灰度图每个像素与平均值来实现的
1.缩放图片,可利用Image对象的resize(size)改变,一般大小为8*8,64个像素值。
2.转化为灰度图
转灰度图的算法。
1.浮点算法:Gray=Rx0.3+Gx0.59+Bx0.11
2.整数方法:Gray=(Rx30+Gx59+Bx11)/100
3.移位方法:Gray =(Rx76+Gx151+Bx28)&&8;
4.平均值法:Gray=(R+G+B)/3;
5.仅取绿色:Gray=G;
在python中,可用Image的对象的方法convert('L')直接转换为灰度图
3.计算平均值:计算进行灰度处理后图片的所有像素点的平均值。
4.比较像素灰度值:遍历灰度图片每一个像素,如果大于平均值记录为1,否则为0.
5.得到信息指纹:组合64个bit位,顺序随意保持一致性。
最后比对两张图片的指纹,获得汉明距离即可。
平均哈希算法过于严格,不够精确,更适合搜索缩略图,为了获得更精确的结果可以选择感知哈希算法,它采用的是DCT(离散余弦变换)来降低频率的方法
一般步骤:
缩小图片:32 * 32是一个较好的大小,这样方便DCT计算
转化为灰度图:把缩放后的图片转化为256阶的灰度图。(具体算法见平均哈希算法步骤)
计算DCT:DCT把图片分离成分率的集合
缩小DCT:DCT计算后的矩阵是32 * 32,保留左上角的8
* 8,这些代表的图片的最低频率
计算平均值:计算缩小DCT后的所有像素点的平均值。
进一步减小DCT:大于平均值记录为1,反之记录为0.
得到信息指纹:组合64个信息位,顺序随意保持一致性。
最后比对两张图片的指纹,获得汉明距离即可。
这里给出别人的DCT的介绍和计算方法(离散余弦变换的方法)
相比pHash,dHash的速度要快的多,相比aHash,dHash在效率几乎相同的情况下的效果要更好,它是基于渐变实现的。
缩小图片:收缩到9*8的大小,以便它有72的像素点
转化为灰度图:把缩放后的图片转化为256阶的灰度图。(具体算法见平均哈希算法步骤)
计算差异值:dHash算法工作在相邻像素之间,这样每行9个像素之间产生了8个不同的差异,一共8行,则产生了64个差异值
获得指纹:如果左边的像素比右边的更亮,则记录为1,否则为0.
最后比对两张图片的指纹,获得汉明距离即可。
这几种算法是识别相似图像的基础,显然,有时两图中的人相似比整体的颜色相似更重要,所以我们有时需要进行人脸识别,
然后在脸部区进行局部哈希,或者进行其他的预处理再进行哈希,这里涉及其他知识本文不作介绍。
下一次将讲述利用opencv和以训练好的模型来进行人脸识别。
本文算法的实现在下面,点一下下面的连接就好
各位亲,走过路过给一个star鼓励一下呗,当然也欢迎提意见。
本文参考文章和图片来源
from:&/a/7183
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1329526次
积分:22240
积分:22240
排名:第247名
原创:427篇
转载:3096篇
评论:172条
(57)(222)(17)(127)(159)(189)(317)(382)(479)(217)(348)(477)(286)(113)(8)(1)(72)(11)(10)(21)(11)
----------coding----------
----------MLCV----------
----------IT笔试面试----------
----------大数据云计算----------
----------Math----------

我要回帖

更多关于 python提取特定字符串 的文章

 

随机推荐