zoukankan      html  css  js  c++  java
  • Atitit 判断判断一张图片是否包含另一张小图片

    Atitit 判断判断一张图片是否包含另一张小图片 

     

    1. keyword1

    2.  模板匹配是在图像中寻找目标的方法之一(切割+图像相似度计算)1

    3. 匹配效果2

    4. 图片相似度的算法(感知哈希算法Perceptual hash algorithm2

    5. 性能结果2

    6. 如何提升性能3

    6.1. 可以采用简化的算法。二次匹配法,先大概确定区域3

    6.2. 切割图片设置一个step3

    7. 参考资料3

    8. ------code3

     

    1. keyword

     

    图像匹配

    图片是否另外一张图片的一部分

    如果是标准图片,模板匹配就好

     

    2.  模板匹配是在图像中寻找目标的方法之一(切割+图像相似度计算)

    Come On, Boy.我们一起来看看模板匹配到底是怎么回事。

    模板匹配的工作方式
        模板匹配的工作方式跟直方图的反向投影基本一样,大致过程是这样的:通过在输入图像上滑动图像块对实际的图像块和输入图像进行匹配。
        假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:
      1)从输入图像的左上角(0,0)开始,切割一块(0,0)(10,10)的临时图像;
      2)用临时图像和模板图像进行对比,对比结果记为c
      3)对比结果c,就是结果图像(0,0)处的像素值;
      4)切割输入图像从(0,1)(10,11)的临时图像,对比,并记录到结果图像;
      5)重复(1)~(4)步直到输入图像的右下角。
        大家可以看到,直方图反向投影对比的是直方图,而模板匹配对比的是图像的像素值;模板匹配比直方图反向投影速度要快一些,但是我个人认为直方图反向投影的鲁棒性会更好。

     

    3. 匹配效果

    效果不错,基本可以确定查找到对应的区域坐标。。对于彩色图片,可以使用色彩空间信息排除掉其他错误的匹配图片,几乎可以精确的确定一个图片了。。

    4. 图片相似度的算法(感知哈希算法Perceptual hash algorithm

    感知哈希算法Perceptual hash algorithm),它的作用是对每张图片生成一个“指纹”(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似。

    下面是一个最简单的实现:

    第一步,缩小尺寸。将图片缩小到8×8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。

    第二步,简化色彩。将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。

    第三步,计算平均值。计算所有64个像素的灰度平均值。

    第四步,比较像素的灰度。将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为。

    第五步,计算哈希值。将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。

    得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算汉明距离。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。

     

     

    5. 性能结果

    在我机子上,语言java ,纯java实现。匹配变换dct算法size 8

    每次移动step=5  。。使用了并行库。。

    速度大概在120s。。懒得继续调整性能了,主要是测试思路,不过总结了思路,暂时先用着,理想的目标应该在3秒内。。

     

    这个是参考文章的说法大概70秒。。语言是c#调用opencv接口

    模板匹配和直方图反向投影的效率
        总的来说,模板匹配和直方图反向投影的效率都不高。在我的机器上,在1136*852大小的输入图像上匹配104*132的大小的模板图像(都是单通道灰度图像),大约需要700毫秒;而直方图反向投影大约需要75000毫秒(1.25分钟)。看来还需要继续学习,寻找更好的处理方法

     

    6. 如何提升性能

    主要算法消耗在匹配小图片上。。

    6.1. 可以采用简化的算法。二次匹配法,先大概确定区域

    。首先可以大幅度的就确定几张疑似图像坐标。。然后对疑似图像进行高精度算法匹配,就可以几乎匹配到唯一的一张。。如果图片是彩色图片,再使用颜色信息二次匹配相似度。。以及直方图等算法补充来匹配。。

    6.2. 切割图片设置一个step

    比如要寻找的图片大小60*60,可以设置一个20%以内的不敬step来跳跃切割,可以大幅度提升性能, 60/0.05=12.。 可以立马提升12倍的性能。。

     

    然后大概选定了区域后,在使用精确移动step来切割图片。

     

    7. 参考资料

     

    如何判断一张图片是否包含另一张小图片?图像匹配?-CSDN论坛-CSDN.NET-中国最大的IT技术社区.html

    模板匹配(Match Template) - Wuya - 博客园.html

    算法 - JPEGDCT压缩原理,谁能通俗易懂解释一下? - SegmentFault.html

    作者:: 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿尔 拉帕努伊 ) 

    汉字名:艾提拉(艾龙)   EMAIL:1466519819@qq.com

    转载请注明来源: http://blog.csdn.net/attilax

     

    8. ------code

     

    private void t() throws IOException {

    String big = "c:\t.jpeg";

    String lit = "c:\lit.jpg";

    // diff==484

     

    BufferedImage lit_img = ImageIO.read(new File(lit));

     

    int w2 = lit_img.getWidth();

    int h2 = lit_img.getHeight();

     

    imgx imgx = new imgx();

    BufferedImage img = ImageIO.read(new File(big));

    int width = img.getWidth();

    int h = img.getHeight();

    ImagePHash imagePHash = new ImagePHash(8, 8);

    ImageReader ImageReader1 = imgx.ImgReader(new File(big));

     

    String ext = filex.getExtName(big);

    imgx.save(lit_img, "c:\0tmpPic\" + filex.getUUidName() + "." + ext, ext);

    ExecutorService es=Executors.newFixedThreadPool(3);

    lab: for (int i = 0; i < width; i = i + 5) {

    for (int j = 0; j < h; j = j + 5) {

    // BufferedImage tmp =

    // (BufferedImage) imgx.cutImage_retImg(big,

    // i, j, w2, h2);

    n++;

    int x = i;

    int y = j;

    int nowCount=n;

    Runnable ra = () -> {

     

    process(lit_img, w2, h2, imgx, imagePHash, ImageReader1, nowCount,

    ext, x, y);

    };

    es.execute(ra);

     

    }

    }

    es.shutdown();

    }

     

    private int process(BufferedImage lit_img, int w2, int h2, imgx imgx,

    ImagePHash imagePHash, ImageReader ImageReader1, int n, String ext,

    int i, int j) {

    Rectangle rect = new java.awt.Rectangle(i, j, w2, h2);

    BufferedImage tmp = imgx.cutImg(rect, ImageReader1);

     

    int dis = imagePHash.distance(tmp, lit_img);

     

    if (dis < 5) {

    log.info(" count:" + String.valueOf(n) + " dis:"

    + String.valueOf(dis) + " rect:" + String.valueOf(i) + "_"

    + String.valueOf(j));

    // break lab;

    }

    if (dis < 10) {

    String out = "c:\0tmpPic\" + filex.getUUidName() + "." + ext;

    imgx.save(tmp, out, ext);

    log.info(" count:" + String.valueOf(n) + " dis:"

    + String.valueOf(dis) + " rect:" + String.valueOf(i) + "_"

    + String.valueOf(j) + " file:" + out);

    }

     

    int cnt = n;

    if (cnt % 100 == 0) {

    String count = String.valueOf(cnt);

     

    log.info(" count:" + count + " dis:" + String.valueOf(dis)

    + " rect:" + String.valueOf(i) + "_" + String.valueOf(j));

    }

    return n;

    }

     

    }

     

    Atiend

     

     

  • 相关阅读:
    LeetCode120 Triangle
    LeetCode119 Pascal's Triangle II
    LeetCode118 Pascal's Triangle
    LeetCode115 Distinct Subsequences
    LeetCode114 Flatten Binary Tree to Linked List
    LeetCode113 Path Sum II
    LeetCode112 Path Sum
    LeetCode111 Minimum Depth of Binary Tree
    Windows下搭建PHP开发环境-WEB服务器
    如何发布可用于azure的镜像文件
  • 原文地址:https://www.cnblogs.com/attilax/p/5963231.html
Copyright © 2011-2022 走看看