在Halftone图像处理方法中,高频振荡法是一种最快的方法,而Bayer法是高频振荡法里最简单的方法。
本文给出了一种Bayer矩阵的生成代码。
本文的代码对作者前面一篇16*16阶的Bayer程序http://blog.youkuaiyun.com/LaPizza/archive/2008/10/29/3173591.aspx 进了大量修改,以面向对象的方式描述了一个Bayer矩阵对象。
首先定义一个描述Bayer矩阵的类BayerMatrix,该类继承了方阵sqMatrix类。
方阵定义如下:
class sqMatrix
{//This is a class of square matrix
public:
sqMatrix(int r);
int getEle(int i, int j);//To get element at Line i, Row j
int getRank();
protected:
int rank;
int *val;
};
包含指向方阵元素的指针 val 和方阵的阶rank,为了方便在BayerMatrix中可以方便地使用数据域,将这些东东放在projected中。
各个函数如何定义,请参照文章后面所附的源代码。
从上面继承生成BayerMatrix
class BayerMatrix:public sqMatrix
{
public:
BayerMatrix(int r);
BayerMatrix();
void Print();
};
主要是要重写构造函数。
重写的构造函数如下:
BayerMatrix::BayerMatrix(int r):sqMatrix(r)
{
if(!Powof2(r)) //estimate wheter the rank is a power of 2
{
cout << "rank should be a power of 2" <<endl;
std::system("pause");
exit(0);
}
val = (int*)malloc(sizeof(int)*r*r);
*(val + rank*0 + 0) = 0;
*(val + rank*0 + 1) = 2;
*(val + rank*1 + 0) = 3;
*(val + rank*1 + 1) = 1;
int b;
b = logl(rank) / logl(2);
for(int k=1; k<b; k++)
{
for(int i=0; i<pow(2,k); i++)
{
for(int j=0; j<pow(2,k); j++)
{
*(val + rank*i + j) *= 4;
*(val + rank*(i+ static_cast<int>(pow(2,k))) + j) = *(val + rank*i + j) + 3;
*(val + rank*i + static_cast<int>((j+pow(2,k)))) = *(val + rank*i + j) + 2;
*(val + rank*(i+static_cast<int>(pow(2,k))) + (j+static_cast<int>(pow(2,k)))) = *(val + rank*i + j) + 1;
}
}
}
}
上述构造函数,利用了Bayer矩阵的生成函数算法,有兴趣的话,可以查看相关文献。
在测试程序中,设计了一个验证Bayer矩阵元素分布情况的函数:
bool checkBayer(LaP::BayerMatrix B)
{//To check whether the built Bayer matrix is corrected.
int rank;
rank = B.getRank();
int min = 256;
int max = -1;
int current;
int up = rank*rank;
for(int i=0; i<up; i++)
{
current = B.getEle(static_cast<int>(i/rank), static_cast<int>(i%rank));
if(current < min)
min = current;
if(current > max)
{
max = current;
}
for(int j=i+1; j<up; j++)
{
if(current == B.getEle(static_cast<int>(j/rank), static_cast<int>(j%rank)))
{
cout << "Error!! The Element["
<< static_cast<int>(i/rank) << "][" << static_cast<int>(i%rank)
<< "] is same to the Element["
<< static_cast<int>(j/rank)<< "][" << static_cast<int>(j%rank)
<< "]" << endl;
return false;
}
}
}
cout << "the min is " << min << endl;
cout << "the max is " << max << endl;
cout << "all the elements are different/n";
return true;
}
来判断Bayer矩阵中元素是否各异,并找出最大最小值。
详细代码如下:
bayer.h文件:
/**************************************************
* File: bayer.h *
* Goal: A declaration of Bayer *
* Version: 1.1p *
* Author: LaPizza (lapizza@163.com) *
* Date: Oct,2008 *
**************************************************/
//
#ifndef BayerH
#define BayerH
#include <iostream>
#include "math.h"
using namespace std;
namespace LaP
{
class sqMatrix
{//This is a class of square matrix
public:
sqMatrix(int r);
int getEle(int i, int j);//To get element at Line i, Row j
int getRank();
protected:
int rank;
int *val;
};
class BayerMatrix:public sqMatrix
{
public:
BayerMatrix(int r);
BayerMatrix();
void Print();
};
//Check whether the input number @n is a power of 2
bool Powof2(int n);
}
#endif
bayer.cpp文件:
/**************************************************
* File: bayer.cpp *
* Goal: A definition of Bayer *
* Version: 1.1p *
* Author: LaPizza (lapizza@163.com) *
* Date: Oct,2008 *
**************************************************/
//
#include <iostream>
#include "bayer.h"
#include "math.h"
bool LaP::Powof2(int n)
{
int t = 1;
for(int i=0; t < n ;i++)
t *= 2;
if(t == n)
return true;
else
return false;
}
void LaP::BayerMatrix::Print()
{
for(int i=0; i<rank; i++)
{
for(int j=0; j<rank; j++)
{
cout << //*(val + i*rank + j)
getEle(i,j) << "/t";
}
cout << endl;
}
}
LaP::sqMatrix::sqMatrix(int r)
{
val = (int*)malloc(sizeof(int)*r*r);
rank = r;
}
int LaP::sqMatrix::getRank()
{
return rank;
}
int LaP::sqMatrix::getEle(int i, int j)
{
return *(val + i*getRank() + j);
}
LaP::BayerMatrix::BayerMatrix(int r):sqMatrix(r)
{
if(!Powof2(r))
{
cout << "rank should be a power of 2" <<endl;
std::system("pause");
exit(0);
}
val = (int*)malloc(sizeof(int)*r*r);
*(val + rank*0 + 0) = 0;
*(val + rank*0 + 1) = 2;
*(val + rank*1 + 0) = 3;
*(val + rank*1 + 1) = 1;
int b;
b = logl(rank) / logl(2);
for(int k=1; k<b; k++)
{
for(int i=0; i<pow(2,k); i++)
{
for(int j=0; j<pow(2,k); j++)
{
*(val + rank*i + j) *= 4;
*(val + rank*(i+ static_cast<int>(pow(2,k))) + j) = *(val + rank*i + j) + 3;
*(val + rank*i + static_cast<int>((j+pow(2,k)))) = *(val + rank*i + j) + 2;
*(val + rank*(i+static_cast<int>(pow(2,k))) + (j+static_cast<int>(pow(2,k)))) = *(val + rank*i + j) + 1;
}
}
}
}
测试文件 bMain.cpp:
/**************************************************
* Project: Bayer.sln (created by VS.net 2003) *
* To get a Bayer matrix for halftone *
* *
* File: bMain.cpp *
* Goal: To test the class of BayerMatrix *
* Version: 0.1T *
* Author: LaPizza (lapizza@163.com) *
* Date: Oct,2008 *
**************************************************/
//
#include <iostream>
using namespace std;
#include "bayer.h"
bool checkBayer(LaP::BayerMatrix B)
{//To check whether the built Bayer matrix is corrected.
int rank;
rank = B.getRank();
int min = 256;
int max = -1;
int current;
int up = rank*rank;
for(int i=0; i<up; i++)
{
current = B.getEle(static_cast<int>(i/rank), static_cast<int>(i%rank));
if(current < min)
min = current;
if(current > max)
{
max = current;
}
for(int j=i+1; j<up; j++)
{
if(current == B.getEle(static_cast<int>(j/rank), static_cast<int>(j%rank)))
{
cout << "Error!! The Element["
<< static_cast<int>(i/rank) << "][" << static_cast<int>(i%rank)
<< "] is same to the Element["
<< static_cast<int>(j/rank)<< "][" << static_cast<int>(j%rank)
<< "]" << endl;
return false;
}
}
}
cout << "the min is " << min << endl;
cout << "the max is " << max << endl;
cout << "all the elements are different/n";
return true;
}
int main()
{
cout << "what is the rank of the matrix you want to build?/n >>";
int ra;
cin >> ra;
LaP::BayerMatrix B(ra);
B.Print();
checkBayer(B);
system("pause");
return 0;
}