首页 > 其他分享 >花40分钟写一个-CBIR引擎-代码公开

花40分钟写一个-CBIR引擎-代码公开

时间:2022-12-22 14:47:44浏览次数:39  
标签:test1 引擎 Mat int 40 hist base CBIR fileinfo

   浏览网页的时候发现一篇不错的文章"用Python和OpenCV创建一个图片搜索引擎的完整指南 " http://python.jobbole.com/80860/. 作者在浏览自己旅游的照片的时候,发现照片太多了分类不过来,一时技痒写了个分类软件,虽然简单但是有用。关键的是我发现他在原文中使用了半个小时就写出来了。【2022年,现在这里的技术已经过时,应该使用milvus】        蛮快的嘛,我想。那么我要用多长时间写出来了,毕竟对于CBIR也是研究过的。        那么立即来做,首先我要找到是图片。我没有那么多旅游图片(汗),但是别人的照片也是可以一样用的。找到了之前专门用于测试CBIR的图片集,大概是这个样子

 

 

  就是各种奇奇怪 怪 的照片。然后搭建opencv的基本框架。我们python用的不熟,但是c++下面自己是有类库的,所以用起来也不是很复杂       
 首先是读入所有的图片:
//递归读取目录下全部文件
void getFiles(string path, vector <string > & files,string flag){
     //文件句柄
     long   hFile    =    0;
     //文件信息
     struct _finddata_t fileinfo;
    string p;
     if((hFile  = _findfirst(p.assign(path).append( "\\*").c_str(), &fileinfo))  !=   - 1){
         do{
             //如果是目录,迭代之,如果不是,加入列表
             if((fileinfo.attrib  &  _A_SUBDIR)){
                 if(strcmp(fileinfo.name, ".")  !=  0   &&  strcmp(fileinfo.name, "..")  !=  0  && flag == "r")
                    getFiles( p.assign(path).append( "\\").append(fileinfo.name), files,flag );
            }
             else{
                files.push_back(p.assign(path).append( "\\").append(fileinfo.name) );
            }
        } while(_findnext(hFile,  &fileinfo)   ==  0);
        _findclose(hFile);
    }
}
//递归读取目录下全部图片
void getFiles(string path, vector <Mat > & files,string flag){
    vector <string > fileNames;
    getFiles(path,fileNames,flag);
     for ( int i = 0;i <fileNames.size();i ++){
        Mat tmp  = imread(fileNames[i]);
         if (tmp.rows > 0) //如果是图片
            files.push_back(tmp);
    }
}
//递归读取目录下全部图片和名称
void getFiles(string path, vector <pair <Mat,string >> & files,string flag){
    vector <string > fileNames;
    getFiles(path,fileNames,flag);
     for ( int i = 0;i <fileNames.size();i ++){
        Mat tmp  = imread(fileNames[i]);
         if (tmp.rows > 0){
               pair <Mat,string > apir;
               apir.first  = tmp;
               apir.second  = fileNames[i];
               files.push_back(apir);
        }
    }
}
然后是编写hsv距离,这个参考以前的资料
double GetHsVDistance(Mat src_base,Mat src_test1){
    Mat   hsv_base;
    Mat   hsv_test1;
     ///  Convert  to  HSV
    cvtColor(  src_base,  hsv_base,  COLOR_BGR2HSV  );
    cvtColor(  src_test1,  hsv_test1,  COLOR_BGR2HSV  );
     ///  Using  50  bins  for  hue  and  60  for  saturation
     int  h_bins   =   50;   int  s_bins   =   60;
     int  histSize[]   =  {  h_bins,  s_bins  };
     //  hue  varies  from  0  to  179,  saturation  from  0  to  255
     float  h_ranges[]   =  {   0,   180  };
     float  s_ranges[]   =  {   0,   256  };
     const   float *  ranges[]   =  {  h_ranges,  s_ranges  };
     //  Use  the  o-th  and  1-st  channels
     int  channels[]   =  {   0,   1  };
     ///  Histograms
    MatND  hist_base;
    MatND  hist_test1;
     ///  Calculate  the  histograms  for  the  HSV  images
    calcHist(   &hsv_base,   1,  channels,  Mat(),  hist_base,   2,  histSize,  ranges,   true,   false  );
    normalize(  hist_base,  hist_base,   0,   1,  NORM_MINMAX,   - 1,  Mat()  );
    calcHist(   &hsv_test1,   1,  channels,  Mat(),  hist_test1,   2,  histSize,  ranges,   true,   false  );
    normalize(  hist_test1,  hist_test1,   0,   1,  NORM_MINMAX,   - 1,  Mat()  );
     ///  Apply  the  histogram  comparison  methods
     double  base_test1   =  compareHist(  hist_base,  hist_test1,   0  );
     return base_test1;
}

 

封装成函数。这个函数比原文中作者提出的方法要简单,我偷懒了。 然后就是要编写主函数程序,这个比较麻烦的地方就是要比较出最前面的10 个图片 。我采用比较笨的方法,赶时间嘛:
int _tmain( int argc, _TCHAR * argv[])
{    
    vector <pair <Mat,string >> imagepairs;
    vector < double > dresult;
     double dmax  =  0;
     int imax  =  - 1;
    
     //读入图片
    getFiles( "images",imagepairs);
    Mat src  = imread( "images/0.jpg");
     //距离测算
     for ( int i = 0;i <imagepairs.size();i ++){
         double tmp  = GetHsVDistance(src,imagepairs[i].first);
         if (tmp  == 1)
            tmp  = 0; //不能搞自己
         char cbuf[ 1024];
        sprintf_s(cbuf, "dst/%d.jpg",i);
        dresult.push_back(tmp); //推入vecresult中
    }
     //寻找前10个图片
     for ( int index  =  0;index < 10;index ++){
         for ( int i = 0;i <imagepairs.size();i ++){
             if (dresult[i] >dmax){
                dmax  = dresult[i];
                imax  = i;
            }
        }
         char cbuf[ 1024];
        sprintf_s(cbuf, "dst/%d.jpg",index);
        imwrite(cbuf,imagepairs[imax].first);
        dresult[imax]  =  0; //剔出队列
        dmax  =  0;
        imax  =  - 1;
    }
    printf( "OK");
    waitKey();
     return  0;
}

 

      前后花了40-50分钟时间,最后的效果不如作者的效果。主要差距在核心算法上面。看来日常的算法总结重构的确很有价值。 这篇文章先写到这里,最近事多,等到闲下来再进行重构。欢迎大家批评指正。  

标签:test1,引擎,Mat,int,40,hist,base,CBIR,fileinfo
From: https://www.cnblogs.com/jsxyhelu/p/16998648.html

相关文章

  • 你真的会搜索吗?搜索引擎指南
    做SEO最重要的一个就是要学会如何搜索,这时可能会有人说往搜索框里输入文字难道还不会?普通的搜索肯定需要会,但是有一些特殊的搜索是SEO必修课程。下面就来介绍一下搜索引擎的......
  • 创元集团的数智化实践 这次选择了和火山引擎 VeDI 搭档
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群近日,上海创元化妆品有限公司(以下简称“创元集团”)与火山引擎数智平台VeDI达成合作,旨......
  • 创元集团的数智化实践 这次选择了和火山引擎 VeDI 搭档
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群近日,上海创元化妆品有限公司(以下简称“创元集团”)与火山引擎数智平台VeDI达成合......
  • ClickHouse MergeTree引擎
    Clickhouse中最强大的表引擎当属MergeTree(合并树)引擎及该系列(*MergeTree)中的其他引擎。MergeTree系列的引擎被设计用于插入极大量的数据到一张表当中。数据可以以数据......
  • Codeforces Round #840 (Div. 2)
    A题意:给定n个整数,可以交换任意两个数二进制上的某一位。求任意操作次数后数组中最大值与最小值的最大差。核心思路:这个思路还是很显然的大胆的猜结论,贪心的考虑每一个......
  • CF1740H MEX Tree Manipulation[动态dp]
    题目描述有一棵不断加叶子的树,叶子的权值是0,其余节点的权值是其子节点的\(\texttt{mex}\)\(\texttt{mex}\)定义为最小的没有出现过的自然数。解题思路首先离线建树,把......
  • 洛谷 P5401 [CTS 2019] 珍珠 题解
    题目链接令\(c_i\)表示第i种颜色的珍珠的数量,显然我们最多能装的瓶数是\(\sum\lfloor\frac{c_i}2\rfloor\)。也就是说,\(c_i\)为奇数的\(i\)的数量不能太多,这个数量要......
  • 通过surging的后台托管服务编写任务调度并支持规则引擎自定义脚本
    简介    过去,如果在业务中需要处理任务调度的时候,大家都会使用第三方的任务调度组件,而第三方组件有一套自己的规则,在微服务的中显得那么格格不入,这样就会造成代码臃......
  • 用户 'NT Service\SSISScaleOutMaster140' 登录失败。 原因: 找不到与提供的名称匹配
    https://www.cnblogs.com/zhengwei-cq/p/14866001.html项目情况:用户‘NTService\SSISScaleOutMaster140’登录失败。原因:找不到与提供的名称匹配的登录名。[客户......
  • mysql federated引擎构建MySQL分布式数据库
    使用mysql federated 引擎构建 MySQL 分布式数据库访问层前言:随着应用复杂度的增加,数据库不断细化切分,导致应用程序中数据库应用就得复杂,凌乱。绝大部分程序人员可能......