SIM = Structural SIMilarity(结构相似性),这是一种用来评测图像质量的一种方法。
由于人类视觉很容易从图像中抽取出结构信息,因此计算两幅图像结构信息的相似性就可以用来作为一种检测图像质量的好坏.首先结构信息不应该受到照明的影响,因此在计算结构信息时需要去掉亮度信息,即需要减掉图像的均值;其次结构信息不应该受到图像对比度的影响,因此计算结构信息时需要归一化图像的方差;最后我们就可以对图像求取结构信息了,通常我们可以简单地计算一下这两幅处理后的图像的相关系数.然而图像质量的好坏也受到亮度信息和对比度信息的制约,因此在计算图像质量好坏时,在考虑结构信息的同时也需要考虑这两者的影响.通常使用的计算方法如下,其中C1,C2,C3用来增加计算结果的稳定性: 2u(x)u(y) + C1L(X,Y) = ------------------------ ,u(x), u(y)为图像的均值 u(x)^2 + u(y)^2 + C1 2d(x)d(y) + C2C(X,Y) = ------------------------,d(x),d(y)为图像的方差 d(x)^2 + d(y)^2 + C2 d(x,y) + C3S(X,Y) = ----------------------,d(x,y)为图像x,y的协方差 d(x)d(y) + C3而图像质量Q = [L(X,Y)^a] x [C(X,Y)^b] x [S(X,Y)^c],其中a,b,c分别用来控制三个要素的重要性,为了计算方便可以均选择为1,C1,C2,C3为比较小的数值,通常C1=(K1 x L)^2, C2=(K2 xL)^2, C3 = C2/2, K1。
谷歌人工智能写作项目:神经网络伪原创
感知哈希算法(perceptual hash algorithm),它的作用是对每张图像生成一个“指纹”(fingerprint)字符串,然后比较不同图像的指纹文案狗。结果越接近,就说明图像越相似。
实现步骤:1. 缩小尺寸:将图像缩小到8*8的尺寸,总共64个像素。
这一步的作用是去除图像的细节,只保留结构/明暗等基本信息,摒弃不同尺寸/比例带来的图像差异;2. 简化色彩:将缩小后的图像,转为64级灰度,即所有像素点总共只有64种颜色;3. 计算平均值:计算所有64个像素的灰度平均值;4. 比较像素的灰度:将每个像素的灰度,与平均值进行比较,大于或等于平均值记为1,小于平均值记为0;5. 计算哈希值:将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图像的指纹。
组合的次序并不重要,只要保证所有图像都采用同样次序就行了;6. 得到指纹以后,就可以对比不同的图像,看看64位中有多少位是不一样的。
在理论上,这等同于”汉明距离”(Hamming distance,在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数)。
如果不相同的数据位数不超过5,就说明两张图像很相似;如果大于10,就说明这是两张不同的图像。
以上内容摘自:下面是用OpenCV实现的测试代码:[cpp] view plaincopyprint?string strSrcImageName = ""; cv::Mat matSrc, matSrc1, matSrc2; matSrc = cv::imread(strSrcImageName, CV_LOAD_IMAGE_COLOR); CV_Assert(matSrc.channels() == 3); cv::resize(matSrc, matSrc1, cv::Size(357, 419), 0, 0, cv::INTER_NEAREST); //cv::flip(matSrc1, matSrc1, 1); cv::resize(matSrc, matSrc2, cv::Size(2177, 3233), 0, 0, cv::INTER_LANCZOS4); cv::Mat matDst1, matDst2; cv::resize(matSrc1, matDst1, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC); cv::resize(matSrc2, matDst2, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC); cv::cvtColor(matDst1, matDst1, CV_BGR2GRAY); cv::cvtColor(matDst2, matDst2, CV_BGR2GRAY); int iAvg1 = 0, iAvg2 = 0; int arr1[64], arr2[64]; for (int i = 0; i < 8; i++) {uchar* data1 = (i);uchar* data2 = (i);int tmp = i * 8;for (int j = 0; j < 8; j++) {int tmp1 = tmp + j;arr1[tmp1] = data1[j] / 4 * 4;arr2[tmp1] = data2[j] / 4 * 4;iAvg1 += arr1[tmp1];iAvg2 += arr2[tmp1];} } iAvg1 /= 64; iAvg2 /= 64; for (int i = 0; i < 64; i++) {arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0;arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0; } int iDiffNum = 0; for (int i = 0; i < 64; i++)if (arr1[i] != arr2[i])++iDiffNum; cout。
图像1和2为RGB图,放在m文件夹下;直接输入二值的话就不用im2bw了,pio是相似比I1=imread('1.jpg');I2=imread('2.jpg');I1_bw=im2bw(I1);%%二值化I2_bw=im2bw(I2);[h,w]=size(I1_bw);%%获取图的宽高h/wsum=0;for i=1:hfor j=1:w if I1_bw(i,j)==I2_bw(i,j)%%逐点比较相似 sum=sum+1; endendendpio=double(sum)/h/w;。
很麻烦,而且计算量很大,这个属于人工智能的范畴。如果这“两张相似图片”可以规定很多前提,比如相同分辨率,黑白,简单几何图形。。。
那么可以用基本的算法去算一下“相似度”, 也就是楼上说的,读取两张照片的像素点,然后遍历去对比灰度差值。
这些有很多现成的算法,也有很多网站提供这方面的计算(直接调用API即可),但是只能得出数字化的“相似度”。如果你要的就是两张图片像素点之间的差异,那么就去找算法即可实现。
看一参考这个网站: 这个是国外比较知名的图像处理的网站。但是,两张图片如果尺寸不一呢? 如果比例不一样呢? 如果有留白呢?彩色的呢?
所以目前最成熟的编程算法也就是识别一下字母和数字(比如谷歌可以识别照片上的门牌号和街道号),人脸识别也只是拿几个标本部位来大致判断相似度(眼睛的大小,鼻梁的高度,脸颊的宽瘦和比例), 以人眼的标准完整的去比较两张图片是否一样是很难的,目前应该还没有这方面成熟的技术。
这种以图搜图可以用感知哈希算法,第一步 缩小图片尺寸 将图片缩小到8x8的尺寸, 总共64个像素. 这一步的作用是去除各种图片尺寸和图片比例的差异, 只保留结构、明暗等基本信息.第二步 转为灰度图片 将缩小后的图片, 转为64级灰度图片.第三步 计算灰度平均值 计算图片中所有像素的灰度平均值第四步 比较像素的灰度 将每个像素的灰度与平均值进行比较, 如果大于或等于平均值记为1, 小于平均值记为0.第五步 计算哈希值 将上一步的比较结果, 组合在一起, 就构成了一个64位的二进制整数, 这就是这张图片的指纹.第六步 对比图片指纹 得到图片的指纹后, 就可以对比不同的图片的指纹, 计算出64位中有多少位是不一样的. 如果不相同的数据位数不超过5, 就说明两张图片很相似, 如果大于10, 说明它们是两张不同的图片.具体的c#代码可以看using System;using ;using System.Drawing; namespace SimilarPhoto{ class SimilarPhoto { Image SourceImg; public SimilarPhoto(string filePath) { SourceImg = Image.FromFile(filePath); } public SimilarPhoto(Stream stream) { SourceImg = Image.FromStream(stream); } public String GetHash() { Image image = ReduceSize(); Byte[] grayValues = ReduceColor(image); Byte average = CalcAverage(grayValues); String reslut = ComputeBits(grayValues, average); return reslut; } // Step 1 : Reduce size to 8*8 private Image ReduceSize(int width = 8, int height = 8) { Image image = SourceImg.GetThumbnailImage(width, height, () => { return false; }, ); return image; } // Step 2 : Reduce Color private Byte[] ReduceColor(Image image) { Bitmap bitMap = new Bitmap(image); Byte[] grayValues = new Byte[image.Width * image.Height]; for(int x = 0; x。
百度识图原理:对于这种百度,谷歌的图像搜索一般由算法实现,一般是三个步骤:1. 将目标图片进行特征提取,描述图像的算法很多,用的比较多的是:SIFT描述子,指纹算法函数,bundling features算法,hash function(散列函数)等。
也可以根据不同的图像,设计不同的算法,比如图像局部N阶矩的方法提取图像特征。2. 将图像特征信息进行编码,并将海量图像编码做查找表。
对于目标图像,可以对分辨率较大的图像进行降采样,减少运算量后在进行图像特征提取和编码处理。
3. 相似度匹配运算:利用目标图像的编码值,在图像搜索引擎中的图像数据库进行全局或是局部的相似度计算;根据所需要的鲁棒性,设定阈值,然后将相似度高的图片预保留下来;最后应该还有一步筛选最佳匹配图片,这个应该还是用到特征检测算法。
其中每个步骤都有很多算法研究,围绕数学,统计学,图像编码,信号处理等理论进行研究。
SSD,即Sum of Squared Differences,就是估算值与估算对象之差值的平方和。一般又称为 Mean Squared Error。
SAD,即Sum of Absolute Differences,就是差的绝对值的和。此算法常用于图像块匹配,将每个像素对应数值之差的绝对值求和,据此评估两个图像块的相似度。
可以看出这个算法很快速、但并不精确,通常用于多级处理的初步筛选。