利用等价LBP特征提取,相似度小于0.65的保存,如果有连续10张相似,则保存第10张,再用它与下一张进行对比。// LBP特征提取冗余处理.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/opencv.hpp> #include <core/core.hpp> #include <stdio.h> #include <iostream> #include <fstream> #include <vector> #include <omp.h> using namespace cv; using namespace std; static int SmallToBig(string &src_1,string &src_2) { //提取字符串中的数字,因为图片格式为XX.jpg,所以提取0-整体数字长度-4 string x=src_1.substr(0,src_1.length()-4); string y=src_2.substr(0,src_2.length()-4); return atoi(x.c_str())<atoi(y.c_str()); } template <typename _tp> //LBP统计,采用等价LBP,8邻域,缩小维度到59 void getLBPfeature(Mat src,Mat dst,int j,int gxid) { int rows=src.rows-2; int cols=src.cols-2; #pragma omp parallel for for (int i=0;i<rows*cols;i++) { //确定中心点坐标 int x=i/rows+1; int y=i%rows+1; _tp centre=src.at<_tp>(x,y); uchar code=0; float neighbors=0; neighbors=src.at<_tp>(x,y-1); code=code|(neighbors>centre)<<7; neighbors=src.at<_tp>(x-1,y-1); code=code|(neighbors>centre)<<6; neighbors=src.at<_tp>(x-1,y); code=code|(neighbors>centre)<<5; neighbors=src.at<_tp>(x-1,y+1); code=code|(neighbors>centre)<<4; neighbors=src.at<_tp>(x,y+1); code=code|(neighbors>centre)<<3; neighbors=src.at<_tp>(x+1,y+1); code=code|(neighbors>centre)<<2; neighbors=src.at<_tp>(x+1,y); code=code|(neighbors>centre)<<1; neighbors=src.at<_tp>(x+1,y-1); code=code|(neighbors>centre)<<0; //根据等价LBP,把原先256维缩短成59维,具体怎么转换可以百度 dst.at<uchar>(x-1,y-1)=LBP_code[code]; } } //LBP查表 uchar LBP_code[256]= { 1, 2, 3, 4, 5, 0, 6, 7, 8, 0, 0, 0, 9, 0, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 14, 0, 15, 16, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 27, 0, 28, 29, 30, 31, 0, 32, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 37, 38, 0, 39, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 44, 0, 45, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 47, 48, 49, 0, 50, 0, 0, 0, 51, 52, 53,0, 54, 55, 56, 57, 58 }; //计算直方图并转换 static Mat hist(Mat &src) { Mat dst; int dims=1; int channel=0; int histsize=59; float range[]={0,58}; const float *ranges={range}; calcHist(&src,1,0,Mat(),dst,dims,&histsize,&ranges,true,false); dst=dst/(int)src.total(); return dst.reshape(1,1); } //把LBP矩阵分成8*8块,并求直方图 static Mat hist_c(Mat src,int gxid_x,int gxid_y,int num ) { int x=src.rows/gxid_x; int y=src.cols/gxid_y; int idx=0; Mat outputimg=Mat::zeros(gxid_x*gxid_y,num,CV_32FC1); for (int i=0;i<gxid_x;i++) { for (int j=0;j<gxid_y;j++) { Mat img=src(Range(0+i*x,x+i*x),Range(0+j*y,y+j*y)); Mat histimg=hist(img); histimg.copyTo(outputimg.row(idx)); idx++; } } return outputimg.reshape(1,1); } static double histcompare(Mat LBP_1,Mat LBP_2) { double ratio=0; ratio=1-compareHist(LBP_1,LBP_2,CV_COMP_BHATTACHARYYA); return ratio; } int main() { int idx=0; vector<string>name; string namespaces; //读图 locale::global(locale("")); ifstream fin("E:\\opencv\\冗余处理\\LIST.TXT"); locale::global(locale("C")); while(getline(fin,namespaces)) { if (namespaces.empty()) { continue; } name.push_back(namespaces); } //因为根据脚本得到LIST.TXT,图像顺序不是正常顺序,所以需要重新排序 sort(name.begin(),name.end(),SmallToBig); //先计算第一张图像的LBP特征 Mat src_1=imread("E:\\opencv\\冗余处理\\"+name[0]); Mat grayimg_1; Mat src_first; cvtColor(src_1,grayimg_1,CV_BGR2GRAY); //缩小运算数据256*256 resize(grayimg_1,src_first,Size(256,256)); Mat lbp_img1=Mat::zeros(src_first.rows-2,src_first.cols-2,CV_8UC1); getLBPfeature<uchar>(src_first,lbp_img1,8,59); Mat first_img=hist_c(lbp_img1,8,8,59); //保存第一张图像 imwrite("E:\\opencv\\冗余处理\\冗余后图像\\"+name[0],src_1); //计算剩余张数的LBP特征 for (int i=1;i<name.size();i++) { Mat src_next=imread("E:\\opencv\\冗余处理\\"+name[i]); Mat grayimg; Mat src; cvtColor(src_next,grayimg,CV_BGR2GRAY); //缩小运算数据256*256 resize(grayimg,src,Size(256,256)); Mat lbp_img=Mat::zeros(src.rows-2,src.cols-2,CV_8UC1); getLBPfeature<uchar>(src,lbp_img,8,59); Mat img=hist_c(lbp_img,8,8,59); //比较两幅图的相似度 double ratio=histcompare(first_img,img); //判断,设置冗余条件 if (ratio<0.65) { imwrite("E:\\opencv\\冗余处理\\冗余后图像\\"+name[i],src_next); idx=0; img.copyTo(first_img); } else { idx++; } //如果连续10张相似,则保存第10张 if (idx==10) { imwrite("E:\\opencv\\冗余处理\\冗余后图像\\"+name[i],src_next); idx=0; img.copyTo(first_img); } } return 0; }
LBP特征提取冗余处理
最新推荐文章于 2022-01-16 15:19:23 发布