相似图像搜索(算法) [原创]

相似图像搜索(算法) [原创]
使用方法:先执行dir *.jpg *.bmp /b /s > imgcmp.lst,然后替换掉原来的imgcmp.lst双击执行imgcmp.exe.
哈哈windows目录下面相同或者相似的文件还是蛮多的嘛.
阈值是相关度判断是否是相似图片的阈值,块大小是图片的分块像素大小.
可执行文件 下载:
下面是截图欣赏:
相似图像搜索(算法) [原创]_第1张图片
相似图像搜索(算法) [原创]_第2张图片
相似图像搜索(算法) [原创]_第3张图片
相似图像搜索(算法) [原创]_第4张图片

  1  RBT < Pair < String,String >   >  img_map;
  2  Int g_limit  =   2 ;
  3  Int g_block  =   32 ;
  4 
  5  RGBQUAD pixel_comp(CxImage *  pImageSrc, CxImage *  pImageDst,Int &  nResult,Byte limit  =   20 )
  6  {
  7      Int src_row  =  pImageSrc -> GetHeight();
  8      Int src_col  =  pImageSrc -> GetWidth();
  9      Byte *  src_buffer  =  pImageSrc -> GetBits();
 10      Int dst_row  =  pImageDst -> GetHeight();
 11      Int dst_col  =  pImageDst -> GetWidth();
 12      Byte *  dst_buffer  =  pImageDst -> GetBits();
 13      RGBQUAD ret  =  { - 1 , - 1 , - 1 , - 1 }, max_ret  =  { 0 };
 14       if (src_row != dst_row  ||  src_col != dst_col) 
 15      {
 16          nResult  =  (dst_row + 2 ) * (dst_col + 1 ) - (src_row + 2 ) * (src_col + 1 );
 17           return  ret;
 18      }
 19 
 20      Double r  =   0 ,g  =   0 ,b  =   0 ,s  =   0 ;
 21      Double abs_r  =   0 ,abs_g  =   0 ,abs_b  =   0 ,abs_s  =   0 ;
 22      Char delta_r  =   0 , delta_g  =   0 , delta_b  =   0 ;
 23      Int Block_Row  =  g_block;
 24      Int Block_Col  =  g_block;
 25  #define  Abs(x) ((x)>=0?(x):-(x))
 26       for (Int i = 0 ; i < (src_row + Block_Row - 1 ) / Block_Row; i ++ )
 27      {
 28           for (Int j = 0 ; j < (src_col + Block_Col - 1 ) / Block_Col; j ++ )
 29          {
 30              Double l_r  =   0 ,l_g  =   0 ,l_b  =   0 ,l_s  =   0 ;
 31              Double l_abs_r  =   0 ,l_abs_g  =   0 ,l_abs_b  =   0 ,l_abs_s  =   0 ;
 32               for (Int k = 0 ; k < Block_Row; k ++ )
 33              {
 34                   for (Int l = 0 ; l < Block_Col; l ++ )
 35                  {
 36                      register Int row  =  i * Block_Row + k;
 37                      register Int idx  =  j * Block_Col + l;
 38                       if (row >= src_row  ||  idx >= src_col)  continue ;
 39                      idx  +=  row * src_col;
 40                      delta_b  =  dst_buffer[idx * 3   ] - src_buffer[idx * 3   ];
 41                      delta_g  =  dst_buffer[idx * 3 + 1 ] - src_buffer[idx * 3 + 1 ];
 42                      delta_r  =  dst_buffer[idx * 3 + 2 ] - src_buffer[idx * 3 + 2 ];
 43 
 44                      l_b  +=  (delta_b);
 45                      l_g  +=  (delta_g);
 46                      l_r  +=  (delta_r);
 47 
 48                      l_abs_b  +=  Abs(delta_b);
 49                      l_abs_g  +=  Abs(delta_g);
 50                      l_abs_r  +=  Abs(delta_r);
 51                  }
 52              }
 53               if (    (max_ret.rgbBlue  = (Byte)l_abs_b / Block_Row / Block_Col) > limit  ||
 54                  (max_ret.rgbGreen = (Byte)l_abs_g / Block_Row / Block_Col) > limit  ||
 55                  (max_ret.rgbRed   = (Byte)l_abs_r / Block_Row / Block_Col) > limit )
 56              {
 57                   return  max_ret;
 58              }
 59 
 60              b  +=  l_b;
 61              g  +=  l_g;
 62              r  +=  l_r;
 63 
 64              abs_b  +=  l_abs_b;
 65              abs_g  +=  l_abs_g;
 66              abs_r  +=  l_abs_r;
 67          }
 68      }
 69  #undef  Abs
 70      max_ret.rgbRed  =  (Byte)(abs_r / src_row / src_col);
 71      max_ret.rgbGreen  =  (Byte)(abs_g / src_row / src_col);
 72      max_ret.rgbBlue  =  (Byte)(abs_b / src_row / src_col);
 73      nResult  =  (Int)((r + g + b) / src_row / src_col);
 74       return  max_ret;
 75  }
 76 
 77  template  < typename T >
 78  T jabs(T t)
 79  {
 80       if ((t  |  ((T)( - 1 ) >> 1 ))  ==  (T)( - 1 ))
 81           return   0 - t;
 82       else
 83           return  t;
 84  }
 85 
 86  Int symbol(Int p)
 87  {
 88       return  p >= 0 ? p: - p;
 89  }
 90 
 91  CStr next_sub(CStr pchSrc, Char match  =   ' \\ ' )
 92  {
 93       int  len  =  strlen(pchSrc);
 94       for ( int  i = len - 1 ; i >= 0 ; i -- )
 95      {
 96           if (pchSrc[i] == match)
 97               return  pchSrc + i + 1 ;
 98      }
 99       return   0 ;
100  }
101 
102  Int img_comp(CStr pchFileSrc,CxImage *  img_src,CStr pchFileDst,CxImage *  img_dst,Byte limit  =   2 )
103  {
104      CStr tmp_str  =  Nul;
105       if (strcmp(pchFileSrc,pchFileDst) == 0 return   0 ;
106       if ( ! img_src -> IsValid())
107      {
108          printf( " parse image (%s) failure!\n " ,pchFileSrc);
109           throw   " parse image failure! " ;
110      }
111       if ( ! img_dst -> IsValid())
112      {
113          printf( " parse image (%s) failure!\n " ,pchFileDst);
114           throw   " parse image failure! " ;
115      }
116      Int nResult;
117      RGBQUAD t  =  pixel_comp(img_src,img_dst,nResult);
118 
119       if ( * (Int * ) & ==   - 1 //  长宽不同,则按名字排序
120           return  (Int)nResult;
121       else   if (jabs(t.rgbBlue) < limit  &&  jabs(t.rgbGreen) < limit  &&  jabs(t.rgbRed) < limit  &&  jabs(t.rgbReserved) < limit)
122      {
123           if (strcmp(pchFileDst,pchFileSrc) != 0 )
124          {
125              img_map.Insert(Pair < String,String > (String(pchFileSrc),String(pchFileDst)));
126              img_map.Insert(Pair < String,String > (String(pchFileDst),String(pchFileSrc)));
127          }
128           return   0 ;
129      }
130       else  
131           return  (Int)nResult;
132  }
133 
134  class  ImageCmp
135  {
136  public :
137      Bool  operator < (ImageCmp &  img)
138      {
139           try {
140               return  img_comp(_img_src.ConvertToCStr(),_img,img._img_src.ConvertToCStr(),img._img,g_limit) < 0 ;
141          } catch (){ return  False;}
142      }
143      CStr GetSrc()                                                                        {  return  _img_src.ConvertToCStr(); }
144      ImageCmp(CStr pchImgSrc) : _img_src(pchImgSrc)
145      {
146          _img  =  New CxImage(pchImgSrc,CxImage::GetTypeIdFromName(next_sub(pchImgSrc, ' . ' )));
147      }
148      ImageCmp( const  String &  sImgSrc) : _img_src(sImgSrc)
149      {
150          CStr tmp_str  =  Nul;
151          _img  =  New CxImage(sImgSrc.ConvertToCStr(),CxImage::GetTypeIdFromName(next_sub(sImgSrc.ConvertToCStr(), ' . ' )));
152      }
153      ImageCmp()                                                                            {_img  =  New CxImage();}
154      AutoPtr < CxImage >  _img;
155  protected :
156      String _img_src;
157  };
158 
159  int  main()
160  {
161      printf( " 阈值: " );
162      scanf( " %d " , & g_limit);
163      printf( " 块大小: " );
164      scanf( " %d " , & g_block);
165      CStr name_cfg  =   " imgcmp.lst " ;
166      Char buffer[MAX_PATH + 1 =  { 0 };
167      Vector < ImageCmp >  vec_file;
168      FILE *  file_cfg  =  fopen(name_cfg, " r " );
169      printf( " loading. " );
170       if (file_cfg)
171      {
172          String last;
173           while ( ! feof(file_cfg))
174          {
175              String tmp;
176              fgets(buffer,MAX_PATH,file_cfg);
177              tmp  =  buffer;
178              tmp.Trim();
179               if ( ! tmp.IsEmpty()  &&  tmp != last)
180              {
181                  vec_file.PushBack(tmp);
182                  printf( " . " );
183              }
184              last  =  tmp;
185          }
186          fclose(file_cfg);
187          file_cfg  =  Nul;
188      }
189      printf( " \nParsing\n " );
190 
191      fast_sort < ImageCmp,Vector < ImageCmp >   > (vec_file, 0 ,vec_file.GetSize() - 1 );
192      printf( " results:\n " );
193      
194      FILE *  html  =  fopen( " output.html " , " w " );
195      fprintf(html, " <HTML><HEAD><TITLE>图片相似度搜索</TITLE></HEAD><BODY>\n " );
196      Bool has_line_draw  =  False;
197      String last_name;
198       for (UInt i = 0 ; i < vec_file.GetSize(); i ++ )
199      {
200          RBT < Pair < String,String >   > ::Iterator iter  =  img_map.Search(vec_file[i].GetSrc());
201           if (iter)
202          {
203               if ( ! last_name.IsEmpty())
204              {
205                  Bool found  =  False;
206                  RBT < String >  src_map,dst_map;
207                  typedef RBT < String > ::Iterator map_iter;
208                   for (RBT < Pair < String,String >   > ::Iterator iter = img_map.Search(last_name);iter;iter = img_map.Search(( * iter).GetVal()))
209                  {
210                      map_iter it  =  src_map.Search(( * iter).GetKey());
211                       if (it)
212                      {
213                           break ;
214                      }
215                      src_map.Insert(( * iter).GetKey());
216                  }
217                   for (RBT < Pair < String,String >   > ::Iterator iter = img_map.Search(vec_file[i].GetSrc());iter;iter = img_map.Search(( * iter).GetVal()))
218                  {
219                       if (src_map.Search(( * iter).GetKey()))
220                      {
221                          found  =  True;
222                           break ;
223                      }
224                      map_iter it  =  dst_map.Search(( * iter).GetKey());
225                       if (it)
226                      {
227                           break ;
228                      }
229                      dst_map.Insert(( * iter).GetKey());
230                  }
231                   if ( ! found)
232                  {
233                      fprintf(html, " <hr>\n " );
234                  }
235              }
236              printf( " %s Same with %s \n " ,vec_file[i].GetSrc(),( * iter).GetVal());
237              fprintf(html, " <a href='file:///%s'>%s</a><br>\n " ,vec_file[i].GetSrc(),vec_file[i].GetSrc());
238              has_line_draw  =  False;
239              last_name  =  vec_file[i].GetSrc();
240          }
241      }
242      fprintf(html, " </body></html> " );
243      fclose(html);
244      ShellExecute(Nul, " open " , " output.html " ,Nul,Nul,SW_SHOW);
245       return   0 ;
246  }
247 

你可能感兴趣的:(相似图像搜索(算法) [原创])