double **matToDouble(Mat src)//将图像转化为二维数组
{
int row = src.rows;
int col = src.cols;
double **a;
a = new double*[row];
for (int i = 0; i < row; i++)
{
a[i] = new double[col];
}
for (int i = 0; i < src.rows; i++)
for (int j = 0; j < src.cols; j++)
{
a[i][j] = (double)src.at < ushort >(i, j);
}
return a;
}
void KUAN(Mat &src, Mat &dst)
{
double **i1, **i2;
i1 = matToDouble(src);
double ybar;
double ystad;
double ENL;
double sx2;
double xcap;
for (int i = 1; i < src.rows - 1; ++i)
for (int j = 1; j < src.cols - 1; ++j)
{
//ybar = (i1[i][j] + i1(i - 1, j - 1) + i1(i - 1, j) + i1(i, j - 1)
//+ i1(i + 1, j) + i1(i, j + 1) + i1(i + 1, j + 1) + i1(i - 1, j + 1) + i1(i + 1, j - 1)) / 9;
ybar = (i1[i - 1][j - 1] + i1[i - 1][j] + i1[i - 1][j + 1] + i1[i][j - 1] + i1[i][j] + i1[i][j + 1] + i1[i + 1][j - 1] + i1[i + 1][j] + i1[i + 1][j + 1]) / 9;
/*ystad = sqrt(((src.at<double>(i, j) - ybar)*(src.at<double>(i, j) - ybar)
+ (src.at<double>(i - 1, j - 1) - ybar)*(src.at<double>(i - 1, j - 1) - ybar)
+ (src.at<double>(i - 1, j) - ybar)*(src.at<double>(i - 1, j) - ybar)
+ (src.at<double>(i, j - 1) - ybar)*(src.at<double>(i, j - 1) - ybar)
+ (src.at<double>(i + 1, j) - ybar)*(src.at<double>(i + 1, j) - ybar)
+ (src.at<double>(i, j + 1) - ybar)*(src.at<double>(i, j + 1) - ybar)
+ (src.at<double>(i + 1, j + 1) - ybar)*(src.at<double>(i + 1, j + 1) - ybar)
+ (src.at<double>(i - 1, j + 1) - ybar)*(src.at<double>(i - 1, j + 1) - ybar)
+ (src.at<double>(i + 1, j - 1) - ybar)*(src.at<double>(i + 1, j - 1) - ybar)) / 9);*/
ystad = sqrt(((i1[i][j] - ybar)*(i1[i][j] - ybar) + (i1[i - 1][j - 1] - ybar)*(i1[i - 1][j - 1] - ybar)
+ (i1[i - 1][j] - ybar)*(i1[i - 1][j] - ybar) + (i1[i][j + 1] - ybar)*(i1[i][j + 1] - ybar)
+ (i1[i][j - 1] - ybar)*(i1[i][j - 1] - ybar) + (i1[i][j + 1] - ybar)*(i1[i][j + 1] - ybar)
+ (i1[i + 1][j - 1] - ybar)*(i1[i + 1][j - 1] - ybar) + (i1[i + 1][j] - ybar)*(i1[i + 1][j] - ybar)
+ (i1[i + 1][j + 1] - ybar)*(i1[i + 1][j + 1] - ybar)) / 9);
ENL = (ybar / (ystad + 0.1))*(ybar / (ystad + 0.1));
sx2 = (ENL*ystad*ystad - ybar*ybar) / (ENL + 1);
xcap = ybar + (sx2*(i1[i][j] - ybar)) / (sx2 + ((ybar*ybar + sx2) / ENL) + 0.1);
if (xcap>16384)
{
xcap = 16384;
}
else if (xcap<0)
{
xcap = 0;
}
else
{
xcap = (int)(xcap + 0.5);
}
dst.at<ushort>(i, j) = xcap;
}
}
void Lee(Mat &src, Mat &dst)
{
double **i1, **i2;
i1 = matToDouble(src);
double ybar;
double ystad;
double ENL;
double sx2;
double xcap;
for (int i = 1; i < src.rows - 1; ++i)
for (int j = 1; j < src.cols - 1; ++j)
{
ybar = (i1[i - 1][j - 1] + i1[i - 1][j] + i1[i - 1][j + 1] + i1[i][j - 1] + i1[i][j] + i1[i][j + 1] + i1[i + 1][j - 1] + i1[i + 1][j] + i1[i + 1][j + 1]) / 9;
ystad = sqrt(((i1[i][j] - ybar)*(i1[i][j] - ybar) + (i1[i - 1][j - 1] - ybar)*(i1[i - 1][j - 1] - ybar)
+ (i1[i - 1][j] - ybar)*(i1[i - 1][j] - ybar) + (i1[i][j + 1] - ybar)*(i1[i][j + 1] - ybar)
+ (i1[i][j - 1] - ybar)*(i1[i][j - 1] - ybar) + (i1[i][j + 1] - ybar)*(i1[i][j + 1] - ybar)
+ (i1[i + 1][j - 1] - ybar)*(i1[i + 1][j - 1] - ybar) + (i1[i + 1][j] - ybar)*(i1[i + 1][j] - ybar)
+ (i1[i + 1][j + 1] - ybar)*(i1[i + 1][j + 1] - ybar)) / 9);
ENL = (ybar / (ystad + 0.1))*(ybar / (ystad + 0.1));
sx2 = (ENL*ystad*ystad - ybar*ybar) / (ENL + 1);
xcap = ybar + (sx2*(i1[i][j] - ybar)) / (sx2 + (ybar*ybar / ENL) + 0.1);
if (xcap > 16384)
{
xcap = 16384;
}
else if (xcap < 0)
{
xcap = 0;
}
else
{
xcap = (int)(xcap + 0.5);
}
dst.at<ushort>(i, j) = xcap;
}
}
对于8位图像,把代码中的ushort改成uchar即可,下面是读取16位raw数据到mat的代码
int RawToMat(const char fileName[], cv::Mat& dst,const int height,const int width)
{
if (fileName == nullptr) return 0;
if ((width <= 0) | (height <= 0)) return 0;
size_t nsize = width * height;
unsigned short *data = new unsigned short[nsize];
FILE *file;
file = fopen(fileName, "rb+");
fread(data, sizeof(unsigned short), nsize, file);
fclose(file);
cv::Mat temp(height, width, CV_16UC1, data);
dst = temp.clone();
return 0;
}
int saveRawFile(const char fileName[], cv::Mat src)
{
if (fileName == nullptr) return 0;
FILE *fw = fopen(fileName, "wb");
fwrite(src.data, src.elemSize(), src.cols * src.rows, fw);
fclose(fw);
return 1;
}
调用测试:
int main()
{
Mat src;
char strPath[256] = "2020/4.raw";
int h = 1024;//1024;
int w = 1024;
RawToMat(strPath, src, h, w);
Mat out = src.clone();
KUAN(src, out);
img.saveRawFile("2020/out.raw", out);//16位数据
waitKey();
return 0;
}
速度比 opencv 的GaussianBlur慢点,cv库的高斯函数也能处理16位图。