图像检索:二维直方图+flann+KNN+欧几里得距离


第一步:批处理提取图像库的二维直方图,并存在到.xml中的featureHists中

第一个参数:图像的路径 目录.txt

第二个参数:图像特征   features.xml

[保存到features.xml中featureHists]

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
using namespace cv;

//计算二维直方图特征
Mat hist2d(const Mat& src);

int main(int argc,char* argv[])
{
  if(argc !=3)
  {
    cerr << "Wrong Argument !" <<endl;
    return -1;
  }
  //定义文件流,只能读取
  ifstream inPutFile(argv[1],ios::in);
  if(! inPutFile)
  {
    cerr << "File Open Erro !" <<endl;
    return -1;
  }
  //读取文件流中的每一行,并赋值给fileName,读取每一幅图像
  string fileName ;
  Mat image;
  Mat featureHist;
  Mat featureHists;
  while (getline(inPutFile,fileName))
  {
    
    image = imread(fileName,1);
    //计算二维直方图特征
    featureHist = hist2d(image);
    //按行存储每一幅图像的二维直方图特征
    featureHists.push_back(featureHist);
  }
  //注意一定要记得关闭文件流
  inPutFile.close();

  /*第五步,把图像特征保存到.xml文件中*/
  FileStorage fs(argv[2],FileStorage::WRITE);
  fs<<"featureHists"<<featureHists;
  fs.release();
  
  return 0;
}

Mat hist2d(const Mat& src)
{
  Mat hsv;

  //颜色空间的转换 BGR2HSV
  cvtColor(src,hsv,CV_BGR2HSV);

  //把H通道分为30个bin,把S通道分为32bin
  int hbins = 30;
  int sbins = 32;
  int histSize[] = { hbins , sbins};

  //H的取值范围 0-179
  float hranges[]= {0,180};
  //S的取值范围 0-255
  float sranges [] ={0,256};
  const float* ranges [] ={hranges,sranges};

  Mat hist2D,histRow,histRowDst;
  //我们根据图像的第一通道和第二通道,计算二维直方图,而且输出的hist2D为32F
  int channels [] ={0,1};
  calcHist(&hsv,1,channels,Mat(),hist2D,2,histSize,ranges,true,false);
  //把直方图特征按一行来存储
  histRow=hist2D.reshape(1,1);

  //把直方图归一化
  normalize(histRow,histRowDst,1,0,NORM_L1);

  return histRowDst;
}
第二步:提取查询图像的二维直方图特征,并保存到.xml中

第一个参数:查询图像的路径

第二个参数:保存查询图像特征的.xml的路径

第三个参数:特征的名字

#include<iostream>
#include<string>
using namespace std;
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
using namespace cv;


int main(int argc,char* argv[])
{
  Mat src = imread(argv[1],1);
  if(! src.data)
  {
    cout <<"No Image" << endl;
    return -1;
  }
    
  Mat hsv;
  //颜色空间的转换BGR2HSV
  cvtColor(src,hsv,CV_BGR2HSV);

  //把H通道分为60个bin,S通道分为32个bin(可以修改)
  int hbins = 60;
  int sbins = 32;
  int histSize[] = { hbins ,sbins};

  //H的取值范围 0-179
  float hranges[]= {0,180};
  //S的取值范围 0-255
  float sranges[] = {0,256};

  const float* ranges [] ={hranges,sranges};
  Mat hist2D,histRow,histRowDst;
  //我们根据图像的第一和第二个通道,计算二维直方图,而且输出的hist2D为32F
  int channels [] ={0,1};
  calcHist(&hsv,1,channels,Mat(),hist2D,2,histSize,ranges,true,false);
  //把直方图特征按一行来存储
  histRow=hist2D.reshape(1,1);

  //把直方图归一化
  normalize(histRow,histRowDst,1,0,NORM_L1);
  FileStorage fs(argv[2],FileStorage::WRITE);
  //把histRowDst保存到.xml文件中
  fs << argv[3] << histRowDst;
  fs.release(); 
  return 0;
}

第三步:从图像库中用K-最近邻算法中,查找和查询图像相似的图片

#include<iostream>
using namespace std;

#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\flann\flann.hpp>
using namespace cv;
int main(int argc,char* argv[])
{
  FileStorage dataBase(argv[1],FileStorage::READ);
  Mat features;
  dataBase["featureHists"]>>features;
  dataBase.release();
  FileStorage queryImage(argv[2],FileStorage::READ);
  Mat queryFeature;
  queryImage[argv[3]]>>queryFeature;
  queryImage.release();
  flann::Index fl(features,flann::KDTreeIndexParams(4));
  Mat index,distance;
  fl.knnSearch(queryFeature,index,distance,1);
  queryImage.release();
  return 0;
}

因为工作的需要把三部分分开了。

这里提供一个基于OpenCV实现的sift+FLANN+ransac+加权融合算法的代码,代码中使用了两幅图像进行拼接。需要注意的是,这段代码仅供参考,具体实现需要根据实际情况进行调整和改进。 ```python import cv2 import numpy as np # 读入两幅图片 img1 = cv2.imread('img1.jpg') img2 = cv2.imread('img2.jpg') # 获取图片大小 rows1, cols1 = img1.shape[:2] rows2, cols2 = img2.shape[:2] # 使用sift算法提取特征点和特征描述子 sift = cv2.xfeatures2d.SIFT_create() keypoints1, descriptors1 = sift.detectAndCompute(img1, None) keypoints2, descriptors2 = sift.detectAndCompute(img2, None) # 使用FLANN算法进行特征点匹配 FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(descriptors1, descriptors2, k=2) # 进行ransac过滤 good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) src_pts = np.float32([keypoints1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2) dst_pts = np.float32([keypoints2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) # 计算拼接后的图像大小 h, w = img1.shape[:2] pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2) dst = cv2.perspectiveTransform(pts, M) dst += (cols1, 0) # 进行图像拼接 result = np.zeros((max(rows1, rows2), cols1 + cols2, 3), dtype=np.uint8) result[:rows1, :cols1, :] = img1 result[:rows2, cols1:, :] = img2 # 加权融合 for i in range(dst.shape[0]): x, y = dst[i][0] x, y = int(x), int(y) if 0 <= x < cols1 + cols2 and 0 <= y < max(rows1, rows2): if x < cols1: result[y, x, :] = img1[y, x, :] elif x >= cols1: result[y, x, :] = img2[y, x - cols1, :] else: result[y, x, :] = (img1[y, x, :] + img2[y, x - cols1, :]) / 2 # 显示拼接后的图像 cv2.imshow('result', result) cv2.waitKey(0) cv2.destroyAllWindows() ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值