LBP特征提取冗余处理

// 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特征提取,相似度小于0.65的保存,如果有连续10张相似,则保存第10张,再用它与下一张进行对比。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值