用双线性插值计算圆形LBP特征中非整数位置的灰度值

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38784454/article/details/79999974
        看了好多文章,都没有对圆形LBP特征中非整数位置的灰度值计算的详细说明,后来读了opencv2写的程序,终于感觉理解了,下面就以半径R=1,点数P=8为例进行讲解。双线性插值说白了就是,非整数点的像素等于周围像素点的加权平均。我们的目的就是求出权值及周围像素点的位置。
       如图求取红点的灰度值,就是求取紫色框中四个像素点灰度值的加权平均。
                                                     
     第一步:蓝色点为中心点,设(i,j),首先求出红点相对于中心点的位置:

     

       第二步:所要加权平均的四个点的位置(x1,y1)(x1,y2)(x2,y1)(x2,y2),floor的意思不大于x的最大整数,ceil的意思是不小于x的最小整数:
        
       第三步:将x,y限制到0到1之间:
    
       第四步:求取f(x1,y1),f(x1,y2),f(x2,y1),f(x2,y2)权系数w1,w2,w3,w4:


       第五步:求取非整数位置的灰度值:

    

    到此就结束了。其他非整数点的灰度值计算类似。

    下面给出具体的opencv2的程序,自己可以尝试一下,看看效果。

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

using namespace cv;
using namespace std;

void elbp1(Mat& src, Mat& dst, int radius, int neighbors)
{
	for (int n = 0; n < neighbors; n++)
	{
		float x = static_cast<float>(radius*cos(CV_PI * 2.0 * n /static_cast<float>( neighbors)));
		float y = static_cast<float>(-radius*sin(CV_PI*2.0*n/static_cast<float>(neighbors)));

		int x1 = static_cast<int>(floor(x));
		int y1 = static_cast<int>(floor(y));
		int x2 = static_cast<int>(ceil(x));
		int y2 = static_cast<int>(ceil(y));

		float tx = x - x1;
		float ty = y - y1;

		float w1 = (1 - tx)*(1 - ty);
		float w2 = tx*(1 - ty);
		float w3 = (1 - tx)*ty;
		float w4 = tx*ty;

		for (int i = radius; i < src.rows - radius; i++)
		{
			for (int j = radius; j < src.cols - radius; j++)
			{
				uchar center = src.at<uchar>(i, j);
				float t = static_cast<float>(w1*src.at<uchar>(i + x1, j + y1) + w2*src.at<uchar>(i + x1, j + y2)\
					+ w3*src.at<uchar>(i + x2, j + y1)+w4*src.at<uchar>(i + x2, j + y2));
				//float t = static_cast<float>(w1*src.at<uchar>(i + x1, j + y1) + w2*src.at<uchar>(i +x1 , j + y2) + w3*src.at<uchar>(i + x2, j + y1) + w4*src.at<uchar>(i + x2, j + y2));
				//dst.at<uchar>(i - radius, j - radius) += ((t > src.at<uchar>(i, j)) || (std::abs(t - src.at<uchar>(i, j)) < std::numeric_limits<float>::epsilon())) << n;
				dst.at<uchar>(i - radius, j - radius) |= (t > center) << (neighbors-n-1);
			}
		}

	}
}

int main()
{
	Mat img = cv::imread("E:\\学习资料\\VS2013程序\\LBP\\8.png",0);
	namedWindow("Image");
	imshow("image",img);
	int radius = 1;
	int neighbors = 8;
	Mat dst1 = Mat(img.rows-2*radius,img.cols-2*radius,CV_8UC1,Scalar(0));
	elbp1(img, dst1, 2, 16);
	namedWindow("dst1");
	imshow("dst1",dst1);
	while (1)
	cv::waitKey(0);
}


    

猜你喜欢

转载自blog.csdn.net/qq_38784454/article/details/79999974
今日推荐