opencv 3/C+PHash 알고리즘 이미지 검색 상세 설명

PHash 알고리즘 은 해시 알고리즘/Perceptual Hash algorithm 을 감지 하여 저주파 의 평균 값 인 해시 를 계산 합 니 다.각 이미지 에 지문 문자열 을 생 성하 고 이 문자열 을 비교 하여 이미지 간 의 싱크로 율 을 판단 할 수 있 습 니 다.
PHash 알고리즘 원리
그림 을 그 레이스 케 일 로 변환 한 후 그림 크기 를 32*32 픽 셀 로 조정 하고DCT 변환을 통 해 왼쪽 상단 의 8*8 픽 셀 영역 을 가 져 옵 니 다.그리고 이 64 픽 셀 의 그 레이스 케 일 값 의 평균 값 을 계산 합 니 다.각 픽 셀 의 그 레이스 케 일 값 과 평균 값 을 비교 하여 평균 값 보다 크 면 1 이 고 평균 값 보다 작 으 면 0 이 며 64 비트 해시 값 을 얻 을 수 있 습 니 다.
PHash 알고리즘 구현
그림 을 그 레이스 케 일 값 으로 변환
그림 사 이 즈 를 32*32 로 축소 합 니 다.

resize(src, src, Size(32, 32));
DCT 변환

 Mat srcDCT; 
 dct(src, srcDCT);
DCT 왼쪽 상단 8*8 픽 셀 영역 평균 값 계산,hash 값 구하 기

 double sum = 0;
 for (int i = 0; i < 8; i++)
  for (int j = 0; j < 8; j++)
   sum += srcDCT.at<float>(i,j);

 double average = sum/64;
 Mat phashcode= Mat::zeros(Size(8, 8), CV_8U);
 for (int i = 0; i < 8; i++)
  for (int j = 0; j < 8; j++)
   phashcode.at<char>(i,j) = srcDCT.at<float>(i,j) > average ? 1:0;
hash 값 일치

  int d = 0;
  for (int n = 0; n < srchash.size[1]; n++)
   if (srchash.at<uchar>(0,n) != dsthash.at<uchar>(0,n)) d++; 
즉,두 폭 의 도 하 쉬 값 사이 의 한 명 거 리 를 계산 하면 한 명 거리 가 클 수록 두 그림 은 비슷 하지 않다 는 것 이다.
OpenCV 구현
그림 에서 각 이미지 와 그림 person.jpg 의 한 명 거 리 를 비교 하여 두 그림 사이 의 액 유사 도 를 평가한다.

#include <iostream> 
#include <stdio.h>
#include <fstream>
#include <io.h>
#include <string>
#include <opencv2\opencv.hpp> 
#include <opencv2\core\core.hpp>
#include <opencv2\core\mat.hpp>
using namespace std; 
using namespace cv; 
int fingerprint(Mat src, Mat* hash);

int main()
{
 Mat src = imread("E:\\image\\image\\image\\person.jpg", 0); 
 if(src.empty())
 {
  cout << "the image is not exist" << endl; 
  return -1;
 }
 Mat srchash, dsthash;
 fingerprint(src, &srchash);
 for(int i = 1; i <= 8; i++)
 { 
  string path0 = "E:\\image\\image\\image\\person";
  string number; 
  stringstream ss; 
  ss << i; 
  ss >> number; 
  string path = "E:\\image\\image\\image\\person" + number +".jpg"; 
  Mat dst = imread(path, 0); 
  if(dst.empty())
  {
   cout << "the image is not exist" << endl; 
   return -1;
  }
  fingerprint(dst, &dsthash);
  int d = 0;
  for (int n = 0; n < srchash.size[1]; n++)
   if (srchash.at<uchar>(0,n) != dsthash.at<uchar>(0,n)) d++; 

  cout <<"person" << i <<" distance= " <<d<<"
"; } system("pause"); return 0; } int fingerprint(Mat src, Mat* hash) { resize(src, src, Size(32, 32)); src.convertTo(src, CV_32F); Mat srcDCT; dct(src, srcDCT); srcDCT = abs(srcDCT); double sum = 0; for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) sum += srcDCT.at<float>(i,j); double average = sum/64; Mat phashcode= Mat::zeros(Size(8, 8), CV_8U); for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) phashcode.at<char>(i,j) = srcDCT.at<float>(i,j) > average ? 1:0; *hash = phashcode.reshape(0,1).clone(); return 0; }
출력 한 밍 거리:

한도 값 을 20 으로 설정 하면 뒤의 세 장의 다른 그림 을 선별 할 수 있 음 을 알 수 있다.
이상 의 opencv 3/C+PHash 알고리즘 이미지 검색 에 대한 상세 한 설명 은 바로 작은 편집 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.여러분 께 참고 가 되 고 저 희 를 많이 사랑 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기