高斯金字塔的思考

首先,关于理论的部分祭上两个博客,

http://blog.csdn.net/poem_qianmo/article/details/26157633

http://amitapba.blog.163.com/blog/static/203610207201281992239/

感觉说的已经比较详细了,在这里我就不搅舌跟子了。

直接上代码:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <boost/concept_check.hpp>

using namespace std;
using namespace cv;
cv::Mat pyrDown(cv::Mat& src);
cv::Mat pyrUp(cv::Mat& src);

static const double gaussianTemplate[7][7] =
{
    {0.00000067, 0.00002292, 0.00019117, 0.00038771, 0.00019117, 0.00002292, 0.00000067},
    {0.00002292, 0.00078633, 0.00655965, 0.01330373, 0.00655965, 0.00078633, 0.00002292},
    {0.00019117, 0.00655965, 0.05472157, 0.11098164, 0.05472157, 0.00655965, 0.00019117},
    {0.00038771, 0.01330373, 0.11098164, 0.22508352, 0.11098164, 0.01330373, 0.00038771},
    {0.00019117, 0.00655965, 0.05472157, 0.11098164, 0.05472157, 0.00655965, 0.00019117},
    {0.00002292, 0.00078633, 0.00655965, 0.01330373, 0.00655965, 0.00078633, 0.00002292},
    {0.00000067, 0.00002292, 0.00019117, 0.00038771, 0.00019117, 0.00002292, 0.00000067}
};

int main(int argc, char **argv) 
{
      Mat src = imread("../0.jpg",-1);
      Mat dst = pyrDown(src);
      Mat dst1 = pyrUp(dst);
      imshow("111",src);
      //cv::waitKey(0);
      imshow("222",dst);
      imshow("333",dst1);
      cv::waitKey(0);
      return 0;
}


//向下取样
cv::Mat pyrDown(cv::Mat& src)
{
      Mat dst;
      dst.create(src.size(),src.type());
      uchar* srcData = src.data;
      uchar* dstData = dst.data;
      //将原始图像进行高斯模糊,高斯卷积过程
      for(int j = 0; j < src.cols-7; j++)
      {
	  for(int i = 0; i < src.rows-7; i++)
	  {
	      double acc = 0;
	      double accb = 0, accg = 0, accr = 0;
	      for(int m = 0; m < 7; m++)
	      {
		for(int n = 0; n < 7; n++)
		{
		      if(src.channels() == 1)
			  acc += *(srcData + src.step * (i+n) + src.channels() * (j+m)) * gaussianTemplate[m][n];
		      else
		      {
			  accb += *(srcData + src.step * (i+n) + src.channels() * (j+m) + 0) * gaussianTemplate[m][n];
			  accg += *(srcData + src.step * (i+n) + src.channels() * (j+m) + 1) * gaussianTemplate[m][n];
			  accr += *(srcData + src.step * (i+n) + src.channels() * (j+m) + 2) * gaussianTemplate[m][n];
		      }
		}
	      }
	      if(src.channels() == 1)
		  *(dstData + dst.step * (i+3) + dst.channels() * (j+3))=(int)acc;
	      else
	      {
		  *(dstData + dst.step * (i+3) + dst.channels() * (j+3) + 0)=(int)accb;
		  *(dstData + dst.step * (i+3) + dst.channels() * (j+3) + 1)=(int)accg;
		  *(dstData + dst.step * (i+3) + dst.channels() * (j+3) + 2)=(int)accr;
	      }
	}
    }
    //将高斯卷积得到的结果取其奇数行和奇数列
    cv::Mat dst1;
    dst1.create(dst.rows/2,dst.cols/2,dst.type());
    uchar* dst1Data = dst1.data;
    //int m = 0,n = 0;
    for(int j = 0,n=0; j < dst.rows-7; j = j + 2,n++)
    {
	for(int i = 0,m=0; i < dst.cols-7; i = i + 2,m++)
	{
	    if(dst.channels() == 1)
		*(dst1Data + dst1.step * n + dst1.channels() * m)=*(dstData + dst.step * j + dst.channels() * i);
	    else
	    {
		*(dst1Data + dst1.step * n + dst1.channels() * m + 0)=*(dstData + dst.step * j + dst.channels() * i + 0);
		*(dst1Data + dst1.step * n + dst1.channels() * m + 1)=*(dstData + dst.step * j + dst.channels() * i + 1);
		*(dst1Data + dst1.step * n + dst1.channels() * m + 2)=*(dstData + dst.step * j + dst.channels() * i + 2);
	    }
	    
	}
	
    }
    return dst1;
    
}
cv::Mat pyrUp(cv::Mat& src)
{
    cv::Mat dst1;
    dst1.create(src.rows*2,src.cols*2,src.type());
    uchar* dst1Data = dst1.data;
    uchar* srcData = src.data;
    //int m = 0,n = 0;
    for(int n=0; n < src.rows; n++)
    {
	for(int m=0; m < src.cols; m++)
	{
	    if(src.channels() == 1)
	    {
	      *(dst1Data + dst1.step * n + dst1.channels() * m) = *(srcData + src.step * n + src.channels() * m);
	      *(dst1Data + dst1.step * n + dst1.channels() * (m+1)) = 0;
	      *(dst1Data + dst1.step * (n+1) + dst1.channels() * m) = 0;
	      *(dst1Data + dst1.step * (n+1) + dst1.channels() * (m+1)) = 0;
	    }
	    else
	    {
		*(dst1Data + dst1.step * 2 * n + dst1.channels()* 2 * m + 0) = *(srcData + src.step * n + src.channels() * m+ 0);
		*(dst1Data + dst1.step * 2 * n + dst1.channels() * 2 * (m+1) + 0) = 0;
		*(dst1Data + dst1.step * 2 * (n+1) + dst1.channels() * 2 * m + 0) = 0;
		*(dst1Data + dst1.step * 2 * (n+1) + dst1.channels() * 2 * (m+1) + 0) = 0;
		
		*(dst1Data + dst1.step * 2 * n + dst1.channels()* 2 * m + 1) = *(srcData + src.step * n + src.channels() * m+ 1);
		*(dst1Data + dst1.step * 2 * n + dst1.channels() * 2 * (m+1) + 1) = 0;
		*(dst1Data + dst1.step * 2 * (n+1) + dst1.channels() * 2 * m + 1) = 0;
		*(dst1Data + dst1.step * 2 * (n+1) + dst1.channels() * 2 * (m+1) + 1) = 0;
		
		*(dst1Data + dst1.step * 2 * n + dst1.channels()* 2 * m + 2) = *(srcData + src.step * n + src.channels() * m+ 2);
		*(dst1Data + dst1.step * 2 * n + dst1.channels() * 2 * (m+1) + 2) = 0;
		*(dst1Data + dst1.step * 2 * (n+1) + dst1.channels() * 2 * m + 2) = 0;
		*(dst1Data + dst1.step * 2 * (n+1) + dst1.channels() * 2 * (m+1) + 2) = 0;
	    }
	}
    }
    //cv::imshow("11",dst1);
    //cv::waitKey(0);
    Mat dst;
    dst.create(dst1.size(),dst1.type());
    uchar* dstData = dst.data;
    for(int j = 0; j < dst1.cols - 7; j++)
      {
	  for(int i = 0; i < dst1.rows - 7; i++)
	  {
	      double acc = 0;
	      double accb = 0, accg = 0, accr = 0;
	      for(int m = 0; m < 7; m++)
	      {
		for(int n = 0; n < 7; n++)
		{
		      if(dst1.channels() == 1)
			  acc += *(dst1Data + dst1.step * (i+n) + dst1.channels() * (j+m)) * gaussianTemplate[m][n]*4;
		      else
		      {
			  accb += *(dst1Data + dst1.step * (i+n) + dst1.channels() * (j+m) + 0) * gaussianTemplate[m][n]*4;
			  accg += *(dst1Data + dst1.step * (i+n) + dst1.channels() * (j+m) + 1) * gaussianTemplate[m][n]*4;
			  accr += *(dst1Data + dst1.step * (i+n) + dst1.channels() * (j+m) + 2) * gaussianTemplate[m][n]*4;
		      }
		}
	      }
	      if(dst1.channels() == 1)
		  *(dstData + dst.step * (i+3) + dst.channels() * (j+3))=(int)acc;
	      else
	      {
		  *(dstData + dst.step * (i+3) + dst.channels() * (j+3) + 0)=(int)accb;
		  *(dstData + dst.step * (i+3) + dst.channels() * (j+3) + 1)=(int)accg;
		  *(dstData + dst.step * (i+3) + dst.channels() * (j+3) + 2)=(int)accr;
	      }
	}
    }
    
    return dst;
}
这段代码主要是实现了高斯金字塔中向下取样算法和向上取样算法。
原文地址:https://www.cnblogs.com/liumantang/p/11830396.html