图像相似度比较和检测图像中的特定物

简介: 图像相似度比较和检测图像中的特定物

对普通人而言,识别任意两张图片是否相似是件很容易的事儿。但是从计算机的角度来识别的话,需要先识别出图像的特征,然后才能进行比对。在图像识别中,颜色特征是最为常见的。每张图像都可以转化成颜色分布直方图,如果两张图片的直方图很接近,就可以认为它们很相似。这有点类似于判断文本的相似程度。


图像比较



先来比对两张图片,一张是原图另一张是经过直方图均衡化之后的图片。


image.png

原图和直方图均衡化比较.png


二者的相关性因子是-0.056,这说明两张图的相似度很低。在上一篇文章 图像直方图与直方图均衡化 中,已经解释过什么是直方图均衡化。通过直方图均衡化后,两张图片确实是不同的,可以从下图看出。


image.png

直方图均值化.png


我们来看看如何使用直方图比较。

final Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.test_hist);
        image0.setImageBitmap(bitmap);
        CV4JImage cv4jImage = new CV4JImage(bitmap);
        ImageProcessor imageProcessor = cv4jImage.convert2Gray().getProcessor();
        int[][] source = null;
        int[][] target = null;
        CalcHistogram calcHistogram = new CalcHistogram();
        int bins = 180;
        source = new int[imageProcessor.getChannels()][bins];
        calcHistogram.calcHSVHist(imageProcessor,bins,source,true);
        if (imageProcessor instanceof ByteProcessor) {
            EqualHist equalHist = new EqualHist();
            equalHist.equalize((ByteProcessor) imageProcessor);
            image1.setImageBitmap(cv4jImage.getProcessor().getImage().toBitmap());
            target = new int[imageProcessor.getChannels()][bins];
            calcHistogram.calcHSVHist(imageProcessor,bins,target,true);
        }
        CompareHist compareHist = new CompareHist();
        StringBuilder sb = new StringBuilder();
        sb.append("巴氏距离:").append(compareHist.bhattacharyya(source[0],target[0])).append("\r\n")
                .append("协方差:").append(compareHist.covariance(source[0],target[0])).append("\r\n")
                .append("相关性因子:").append(compareHist.ncc(source[0],target[0]));
        result.setText(sb.toString());


其中,CompareHist 这个类是用于直方图比较的类。


然后,再来比较两张完全一致的图片,可以看到他们的相关性因子是1.0,表示两者完全一致。


image.png

两张相同的图比较.png


最后,来比对两张完全不同的图片,可以看到它们的相关性因子是0.037,表面二者几乎没有什么相似之处。


image.png

两张完全不同的图比较.png


直方图比较是识别图像相似度的算法之一,也是最简单的算法。当然,还有很多其他的算法啦。


直方图反向投影



所谓反向投影就是首先计算某一特征的直方图模型,然后使用模型去寻找图像中存在的该特征。


image.png

反向投影的算法.png


其中,b(xi)表示在位置xi上像素对应的直方图第b(xi)个bin,直方图共m个bin,qu表示第u个bin的值。


下图是皇马的拉莫斯在2017年欧冠决赛时的图片。直方图反向投影可以根据球员球衣中的某一块区域,来查找图片中拉莫斯所穿的球衣。


image.png

直方图反向投影.png


上图是不是很酷炫?来看看是怎样使用反向投影的,需要先计算出样本的直方图,然后使用模型去寻找原图中存在的该特征。反向投影的结果包含了:以每个输入图像像素点为起点的直方图对比结果。在这里是一个单通道的浮点型图像。

Resources res = getResources();
        Bitmap bitmap1 = BitmapFactory.decodeResource(res, R.drawable.test_project_target);
        targetImage.setImageBitmap(bitmap1);
        Bitmap bitmap2 = BitmapFactory.decodeResource(res, R.drawable.test_project_sample);
        sampleImage.setImageBitmap(bitmap2);
        CV4JImage cv4jImage = new CV4JImage(bitmap1);
        ColorProcessor colorProcessor = (ColorProcessor)cv4jImage.getProcessor();
        BackProjectHist backProjectHist = new BackProjectHist();
        int w = colorProcessor.getWidth();
        int h = colorProcessor.getHeight();
        CV4JImage resultCV4JImage = new CV4JImage(w,h);
        ByteProcessor byteProcessor = (ByteProcessor)resultCV4JImage.getProcessor();
         // sample
        CV4JImage sample = new CV4JImage(bitmap2);
        ColorProcessor sampleProcessor = (ColorProcessor)sample.getProcessor();
        CalcHistogram calcHistogram = new CalcHistogram();
        int bins = 32;
        int[][] hist = new int[sampleProcessor.getChannels()][bins];
        calcHistogram.calcHSVHist(sampleProcessor,bins,hist,true);
        byte[][] source = new byte[][]{colorProcessor.getRed(),colorProcessor.getGreen(),colorProcessor.getBlue()};
        byte[][] target = new byte[3][w*h];
        Tools.rgb2hsv(source,target);
        ByteProcessor hsvByteProcessor = new ByteProcessor(target[0],w,h);
        backProjectHist.backProjection(hsvByteProcessor,byteProcessor,hist[0],new int[]{0,180});
        result.setImageBitmap(byteProcessor.getImage().toBitmap());


其中,BackProjectHist 这个类是用于直方图反向投影的类。


总结



直方图比较和直方图反向投影的算法都已经包含在cv4j中。


cv4jgloomyfish和我一起开发的图像处理库,纯java实现,目前还处于早期的版本。这次我们填完直方图的坑以后,终于把它发布到jcenter上了。


单独下载cv4j

compile 'com.cv4j:cv4j:0.1.0'


也可以下载rxcv4j,它是使用 RxJava2.x 进行的封装,如果下载该模块的话无需再下载cv4j。

compile 'com.cv4j:rxcv4j:0.1.0'


目前已经实现的功能:


image.png

cv4j.png


下周我们开始做模板匹配的算法。

相关文章
|
29天前
|
机器学习/深度学习 编解码 测试技术
图像超分:真实感图像超分辨率的局部判别学习方法
图像超分:真实感图像超分辨率的局部判别学习方法
26 0
|
3月前
图像表示方法
图像表示方法
17 0
|
4月前
|
计算机视觉
图像降噪方法:
图像降噪方法: 图像降噪是图像处理中的一项重要任务,可以通过减少图像中的噪声来提高图像的质量。常见的降噪方法包括: - 均值滤波:对图像中的每个像素取平均值,降低噪声。 - 中值滤波:对图像中的每个像素取邻域内像素的中值,降低脉冲噪声和椒盐噪声。
177 1
|
7月前
|
机器学习/深度学习 传感器 算法
【图像分割】图像检测(分割、特征提取)、各种特征(面积等)的测量和过滤(Matlab代码实现)
【图像分割】图像检测(分割、特征提取)、各种特征(面积等)的测量和过滤(Matlab代码实现)
|
10月前
|
文字识别 算法 计算机视觉
计算机视觉图像常用基本算法(阈值化、形态学变化、模糊)
计算机视觉图像常用基本算法(阈值化、形态学变化、模糊)
125 0
|
10月前
图像的点运算1
图像的点运算1
|
机器学习/深度学习 传感器 文字识别
【图像检测】基于计算机实现交通标志图像检测提取附matlab代码和报告
【图像检测】基于计算机实现交通标志图像检测提取附matlab代码和报告
|
机器学习/深度学习 传感器 算法
【图像分割】基于超像素的快速模糊聚类算法(SFFCM) 实现彩色图像分割附matlab代码
【图像分割】基于超像素的快速模糊聚类算法(SFFCM) 实现彩色图像分割附matlab代码
|
算法 数据可视化 索引
ML之SIFT_FLANN:对图片提取SIFT特征并利用FLANN方法判别图像的相似度并可视化
ML之SIFT_FLANN:对图片提取SIFT特征并利用FLANN方法判别图像的相似度并可视化
ML之SIFT_FLANN:对图片提取SIFT特征并利用FLANN方法判别图像的相似度并可视化
|
机器学习/深度学习 算法 计算机视觉
图像数据与边缘检测
图像数据与边缘检测
125 0
图像数据与边缘检测