首页 > 学院 > 开发设计 > 正文

自适应方向提升小波去噪

2019-11-08 02:27:00
字体:
来源:转载
供稿:网友

提升小波与方向提升小波

标签(空格分隔): 算法学习


1、第二代提升小波

……(留在日后填写,原理以及实现细节,这里先直接贴程序吧)

2、自适应方向提升小波

2.1main函数

clear all;close all;clc%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%此文件主要实现一种简单的自适应方向小波去噪%%基于第二代提升小波的预测和更新两个步骤%%%%%% 调参数%%%%%%img_ori = double(imread('test.bmp'));%读入图像if size(img_ori,3) == 3; img_ori = rgb2gray(img_ori);end;[img_rows,img_cols] = size(img_ori);var_noise = 20;%噪声方差img_noise = addNoise(img_ori,var_noise);%给图像加入高斯噪声tic%正变换[LL,LH,HL,HH,dir_mat11,dir_mat12] = ADL97(img_noise,1);[LL2,LH2,HL2,HH2,dir_mat21,dir_mat22] = ADL97(LL,2);[LL3,LH3,HL3,HH3,dir_mat31,dir_mat32] = ADL97(LL2,3);%系数处理thr=sqrt(1*mean(abs(HH(:)))/0.6745)*sqrt(2*log(img_rows*img_cols));%%阈值计算[LH,HL,HH]=softDe(LH,HL,HH,thr,1);[LH2,HL2,HH2]=softDe(LH2,HL2,HH2,thr,2);[LH3,HL3,HH3]=softDe(LH3,HL3,HH3,thr,3);%反变换LL2 = IADL97(LL3,LH3,HL3,HH3,dir_mat31,dir_mat32);LL = IADL97(LL2,LH2,HL2,HH2,dir_mat21,dir_mat22);out_img = IADL97(LL,LH,HL,HH,dir_mat11,dir_mat12);tocnois_PSNR = calcuPSNR(double(img_ori),double(img_noise));recons_PSNR = calcuPSNR(double(img_ori),double(out_img));imwrite(uint8(out_img),'recons.bmp');

2.2 ADL97正变换

function [LL,LH,HL,HH,dir_mat,dir_mat2] = ADL97(img,decom_level)%%% 输入:待处理图像,分解级数%%% 输出:小波分解系数LL,LH,HL,HH%%% 提升小波系数: alfa: -1.586134342%%% beta: -0.052980118%%% gamma: 0.0882911075%%% delta:0.443506852%%% coef:1.230174105%设置提升系数alfa = -1.586134342;beta = -0.052980118;gamma = 0.882911075;delta = 0.443506852;coef = 1.230174105;%得到方向矩阵,大小与输入图像大小一致dir_mat = getDirMat(img,1,decom_level);% dir_mat = getDirMat2(img,1);%% 接下来是97二代提升小波核心步骤 %%%%%%%%%%%%%%%%%%============行变换 flag ==1 =================%%%%%%%%%%%flag = 1;%预测 step = 1step =1;img = singleLifting(img,flag,step,alfa,dir_mat);%更新 step = 2step =2;img = singleLifting(img,flag,step,beta,dir_mat);%预测 step = 1step =1;img = singleLifting(img,flag,step,gamma,dir_mat);%更新 step = 2step =2;img = singleLifting(img,flag,step,delta,dir_mat);%提取高频分量high_freq = img(1:2:end,:)/coef;%提取低频分量low_freq = img(2:2:end,:)*coef;%% 将提取到的高频分量再次进行上述步骤,得到HL,HH%%%%%%%%%%%%%%%%%%============列变换 flag ==2 =================%%%%%%%%%%%flag = 2;%预测 step = 1step =1;high_freq =singleLifting(high_freq,flag,step,alfa);%更新 step = 2step =2;high_freq = singleLifting(high_freq,flag,step,beta);%预测 step = 1step =1;high_freq=singleLifting(high_freq,flag,step,gamma);%更新 step = 2step =2;high_freq=singleLifting(high_freq,flag,step,delta);%提取高频分量,HHHH = high_freq(:,1:2:end)/coef;%提取低频分量HL = high_freq(:,2:2:end)*coef;%% 再做一次方向预测,得到LL,LH;dir_mat2 = getDirMat(low_freq,2,decom_level);% dir_mat2 = getDirMat2(img,1);%预测 step = 1step =1;low_freq = singleLifting(low_freq,flag,step,alfa,dir_mat2);%更新 step = 2step =2;low_freq = singleLifting(low_freq,flag,step,beta,dir_mat2);%预测 step = 1step =1;low_freq = singleLifting(low_freq,flag,step,gamma,dir_mat2);%更新 step = 2step =2;low_freq = singleLifting(low_freq,flag,step,delta,dir_mat2);%提取高频分量,LHLH = low_freq(:,1:2:end)/coef;LL = low_freq(:,2:2:end)*coef;end

2.3方向预测

function dir_mat = getDirMat(img,flag,decom_level)%%% 输入: %%% img :待处理图像 double%%% flag: 处理步骤 flag==1, 当前处理为行操作 flag== 2, 当前处理为列操作%%% decom_levle:小波分解级数%%% blk_size: 窗内所有分解采用一个方向 初始定为16%%% 输出:%%% dir_mat = 方向矩阵,大小与输入图像大小相同blk_size =32;win_size = blk_size/(2^(decom_level -1 ));%分块大小%将整个图像分成大小为win*win的块进行计算blk_img = getBlock(img,win_size);[rows,cols] = size(blk_img);for i = 1: rows for j =1:cols dir_mat(i,j)=dir_est(blk_img{i,j},flag); endend[m,n] =size(dir_mat);for i =1:m for j =1:n y{i,j}=dir_mat(i,j)*ones(win_size,win_size); endenddir_mat = cell2mat(y);endfunction blk_img = getBlock(img,win_size)%%% 对图像进行分块%%% 输入:%%% img:输入的待分块图像%%% win_size:块的大小%%% 输入图像的长和宽必须为win_size的整数倍大小[rows,cols] = size(img);count_rows = rows/win_size;count_cols = cols/win_size;for i = 1:count_rows for j =1:count_cols blk_img{i,j}=img((i-1)*win_size+1:i*win_size,(j-1)*win_size+1:j*win_size); endendendfunction dir = dir_est(blk_img,flag)%%%输入:%%% img:待处理图像块%%% flag: 处理步骤 flag==1, 当前处理为行操作 flag== 2, 当前处理为列操作%%%输出:%%% dir:输入图像块中的选取方向%%% 选取原则为高频能量最小if flag == 2; blk_img = blk_img';end%遍历所有方向,由于是simple ADL,这里只取三个方向temp = blk_img;for k = -1:1 blk_img = temp; blk_img = padarray(blk_img,[2,1],'symmetric','both');%边界扩展 blk_img(2,:) = []; blk_img(end-1,:) = []; [rows,cols] = size(blk_img); %%%是否需要插值,我不知道 for i = 2:2:rows-1 for j = 2:cols-1 blk_img(i,j) = blk_img(i,j) - 0.5*( blk_img(i-1,j+k) + blk_img(i+1,j-k)); end end blk_img = blk_img(2:end-1,2:end-1); high_freq = blk_img(1:2:end,:); power_high(k+2) = norm(high_freq(:),2)^2;end[~,idx] = min(power_high);dir = idx -2;end

2.4单步提升

function img = singleLifting(img, flag, step,coe,dir_mat)%%%输入:%%% img:待处理图像%%% flag:行变换或者列变换的标志, flag==1:行变换 flag==2:列变换%%% step:预测或者更新的标志 step==1:预测 step==2:更新%%% dir_mat:方向矩阵%%%输出:%%% img[m,n] = size(img);if nargin == 4 dir_mat=zeros(m,n);endif flag==2 img =img'; dir_mat = dir_mat';endimg = wextend('2','symw',img,1);%图像向外扩展一圈if step ==1 %预测 img(end,:)=[];elseif step==2 %更新 img(1,:)=[];end%%%%%%这里不需要插值[rows,cols] = size(img);for k = 2:2:rows-1 img(k,2:cols-1) = img(k,2:cols-1) + coe*( img(k-1,(2:cols-1)+dir_mat(k-1,:)) + img(k+1,(2:cols-1)-dir_mat(k-1,:)));endif step ==1 img = img(2:end,2:end-1);elseif step ==2 img = img(1:end-1,2:end-1);endif flag==2 img = img';endend

2.5反变换

function img = IADL97(LL,LH,HL,HH,dir_mat,dir_mat2)%%%输入:%%% LL,LH,HL,HH为小波分解的系数矩阵%%% dir_mat,dir_mat2为方向矩阵%%%输出: %%% img:小波逆变换的重构矩阵alfa = 1.586134342;beta = 0.052980118;gamma = -0.882911075;delta = -0.443506852;coef = 1.230174105;%计算high——freqHH = HH *coef;HL = HL /coef;LH = LH *coef;LL = LL /coef;[m,n]=size(HH);high_freq = [];for i =1:n high_freq = [high_freq,HH(:,i),HL(:,i)];end[m,n] = size(high_freq);high_freq = singleLifting(high_freq,2,2,delta);high_freq = singleLifting(high_freq,2,1,gamma);high_freq = singleLifting(high_freq,2,2,beta);high_freq = singleLifting(high_freq,2,1,alfa);high_freq = high_freq * coef;low_freq = [];[m,n] = size(LL);for i =1:n low_freq = [low_freq,LH(:,i),LL(:,i)];end[m,n] = size(low_freq);low_freq = singleLifting(low_freq,2,2,delta,dir_mat2);low_freq = singleLifting(low_freq,2,1,gamma,dir_mat2);low_freq = singleLifting(low_freq,2,2,beta,dir_mat2);low_freq = singleLifting(low_freq,2,1,alfa,dir_mat2);low_freq = low_freq /coef;img = [];for i =1:m img = [img;high_freq(i,:);low_freq(i,:)];end% [m,n] = size (img);img = singleLifting(img,1,2,delta,dir_mat);img = singleLifting(img,1,1,gamma,dir_mat);img = singleLifting(img,1,2,beta,dir_mat);img = singleLifting(img,1,1,alfa,dir_mat);end

3、基于方向提升小波改进的一些

在做卫星图像质量提高的时候,相机噪声通常都是很大的,在项目里面采用了5-3提升方向小波,为了提高程序的运行速度,将原来的9个方向缩减为现在的3个方向,这么做的好处是什么呢?当采用9个方向的方向提升小波时,需要对图像进行预处理插值,9个方向时需要分别插出1/2像素点和1/4像素点。依次类推,采用5个方向预测时,则只需要插出1/2像素点。预测3个方向时,则不需要提前对图像进行插值。 在写c语言的时候,我也重新整理了一下3方向提升小波,下面我按照思路将程序一块块的贴上来:

3.1 正变换

方向提升小波的正变换对应于小波正变换,会得到图像的LL,LH,HL,HH四个分量,分别对应于图像的低频分量,水平方向上的高频分量,垂直方向上的高频分量以及45度角上的高频分量。

cout << "----------------------wavelet denoise start---------------------" << endl; Mat * img_in = new Mat(); Mat * img_out = new Mat(); *img_in = Mat::zeros(rows_ori, cols_ori, CV_64FC1); *img_out = Mat::zeros(rows_ori, cols_ori, CV_64FC1); // double * img_ori_ptr ---> Mat::img_ori int ptr_bias = 0; for (int i = 0; i < rows_ori; ++i) { for (int j = 0; j < cols_ori; ++j) { img_in->at<double>(i, j) = *(image_in + ptr_bias); ptr_bias++; } } int rows = img_in->size().height; int cols = img_in->size().width; clock_t start, end; start = clock(); cout << "------step1: Forward Transform-----" << endl; ////////////////////////////////小波一级分解/////////////////////////////// Mat* LL = new Mat(); LL->create(rows / 2, cols / 2, CV_64FC1); Mat* LH = new Mat(); LH->create(rows / 2, cols / 2, CV_64FC1); Mat* HL = new Mat(); HL->create(rows / 2, cols / 2, CV_64FC1); Mat* HH = new Mat(); HH->create(rows / 2, cols / 2, CV_64FC1); int *dir_mat11 = new int[rows * cols]; int *dir_mat12 = new int[(rows / 2) * cols]; ADL97(img_in, 1, LL, LH, HL, HH, dir_mat11, dir_mat12, blk_size);

上述函数分别完成了将double型的图像指针转换到mat矩阵中,并提前为LL,LH,HL,HH分配好内存空间,其中dirMat变量用来存放预测的方向矩阵,方向矩阵中的取值为,-1,0,1分别对应于三个方向(左上-右下,上-下,右上-左下)。

3.1.1 方向预测

方向预测的过程是对图像块进行处理,在程序中对512*512的图像进行方向预测时默认的块大小为32*32,小波二级分解时图像块的大小变为16*16,三级分解变为8*8。在此处编程时,应用到了一个常用的技巧,即就是取出图像块,对图像块进行处理,再将处理后的图像块放置回原图对应的位置。 下面的getBlock和setBlock函数就是进行上述取块放块操作:

void getBlock(Mat* img, double * blk_img, int* blk_position) { /*对图像进行分块 输入: img:输入的待分块图像 win_size : 块的大小 输入图像的长和宽必须为win_size的整数倍大小 输出: blk_img:图像块 double* */ int p_rows_f = blk_position[0];// 首行 int p_rows_l = blk_position[1];// 末行 int p_cols_f = blk_position[2];// 首列 int p_cols_l = blk_position[3];// 末列 int r_rows = p_rows_l - p_rows_f; int r_cols = p_cols_l - p_cols_f; for (int i = p_rows_f, r_i = 0; i < p_rows_l; i++, r_i++) { for (int j = p_cols_f, r_j = 0; j < p_cols_l; j++, r_j++) { blk_img[r_i*r_cols + r_j] = img->at<double>(i,j); } } }void setBlock(int* dir_mat, int* blk_img, int* blk_position,int img_cols){ /* 输入: blk_img:图像块 double*块中的数据位当前块的预测方向,取值应为(-1,0,1,); blk_position:当前块四个顶点的左边索引 img_cols:输入图像的列数 输出: dir_mat:由所有块拼接而成的方向矩阵,大小与输入图像一致; */ //将小图像块拼接称为整个图像 int p_rows_f = blk_position[0];// 首行 int p_rows_l = blk_position[1];// 末行 int p_cols_f = blk_position[2];// 首列 int p_cols_l = blk_position[3];// 末列 int r_rows = p_rows_l - p_rows_f; int r_cols = p_cols_l - p_cols_f; for (int i = p_rows_f, r_i = 0; i<p_rows_l; i++, r_i++) { for (int j = p_cols_f, r_j = 0; j<p_cols_l; j++, r_j++) { dir_mat[i * img_cols + j] = blk_img[r_i * r_cols + r_j]; /*cout << i << endl;*/ } }}

下面贴出方向预测的主函数:

void getDirMat(Mat* img, int flag, int decom_level, int* dir_mat,int blk_size){ /* 输入: img:待处理图像 Mat* flag:当前处理标志 flag == 1:列变换 flag == 2:行变换 decom_level:分解级数 输出: dir_mat:方向矩阵 int* 大小与输入图像一致 */ int win_size = blk_size / (pow(2, (decom_level - 1))); int rows = img->size().height; int cols = img->size().width; int count_rows = rows / win_size; int count_cols = cols / win_size; //当前块的位置 double* blk_img = new double[win_size * win_size]; int blk_position[4] = { 0 }; int temp; int* temp_mat = new int[win_size * win_size]; //将图像分解成win*win的块进行计算 for (int i = 0; i < count_rows; i++) { for (int j = 0; j < count_cols; j++) { //当前块的四个角坐标索引 blk_position[0] = i * win_size; blk_position[1] = (i + 1) * win_size; blk_position[2] = j * win_size; blk_position[3] = (j + 1) * win_size; //读取到当前块 getBlock(img, blk_img, blk_position); //对当前块进行方向预测 temp = dirEstimation2(blk_img, flag, win_size); for (int k = 0; k < win_size * win_size; k++) { temp_mat[k] = temp; } setBlock(dir_mat, temp_mat, blk_position, cols); } } delete[] blk_img; delete[] temp_mat;}

其中子函数dirEstimation2对输入的图像块用奇数行预测偶数行,偶数行就包含了高频信息,分别计算是哪个方向预测出的高频矩阵,取高频矩阵二范数最小,即能说明该方向的预测是准确的,块中所有点都为此方向。下面贴出方向预测的代码:

void matTrans(int* mat, int* mat_T, int rows, int cols){ for (int i = 0; i < cols; i++) { for (int j = 0; j < rows; j++) { mat_T[i*rows + j] = mat[j*cols + i]; } } }int minIdx(double* power, int data_size){ double min = power[0]; int idx = 0; for (int i = 1; i < data_size; i++) { if (power[i] < min) { min = power[i]; idx = i; } } return idx;}double calcuPower(double* high_freq, int win_size){ double sum = 0; for (int i = 0; i < win_size / 2 ; i++) { for (int j = 0; j < win_size ; j++) { sum = sum + pow(high_freq[i*win_size + j] ,2); } } return sum;}void downSampling(double* img, int win_size, double* high_freq,int flag){ if (flag == 1)//列变换(行下2采样) { for (int i = 0; i < win_size / 2; i++) { for (int j = 0; j < win_size; j++) { high_freq[i*win_size + j] = img[(2 * i)*win_size + j]; } } } if (flag == 2)//行变换(列下2采样) { for (int i = 0; i < win_size; i++) { for (int j = 0; j < win_size / 2; j++) { high_freq[i * win_size / 2 + j] = img[i*win_size + (2*j)]; } } }}int dirEstimation2(double* blk_img, int flag, int win_size){ double power[3] = { 0 }; double* high_freq_mat = new double[win_size * (win_size / 2)]; memset(high_freq_mat, 0, sizeof(double)*win_size*(win_size / 2)); //把图像块的内容暂存在blk的Mat* 里面 Mat* blk_mat_img = new Mat(); blk_mat_img->create(win_size, win_size, CV_64FC1); //边界扩展后的图像块 Mat* blk_expanded_rows = new Mat(); blk_expanded_rows->create(win_size + 2, win_size , CV_64FC1); Mat* blk_expanded_cols = new Mat(); blk_expanded_cols->create(win_size + 2, win_size + 2, CV_64FC1); //把double*的图像块数据存放在Mat矩阵里面 for (int i = 0; i < win_size; i++) { for (int j = 0; j < win_size; j++) { blk_mat_img->at<double>(i, j) = blk_img[i*win_size + j]; } } if (flag == 1)//当前为列操作 { for (int k = -1; k < 2; k++) { //循环之前,需要将blk_mat_img的数据重新赋值给blk_expanded,并填充边框 copyMakeBorder(*blk_mat_img, *blk_expanded_rows, 1, 1, 0, 0, BORDER_REFLECT_101); copyMakeBorder(*blk_expanded_rows, *blk_expanded_cols, 0, 0, 1, 1, BORDER_REFLECT); //数据准备完毕,进行方向预测 for (int i = 1; i < win_size + 1; i = i + 2) { for (int j = 1; j < win_size + 1; j++) { blk_expanded_cols->at<double>(i, j) = blk_expanded_cols->at<double>(i, j) - 0.5*( blk_expanded_cols->at<double>(i-1,j+k) + blk_expanded_cols->at<double>(i+1,j-k) ); } } for (int i = 0; i < win_size; i++) { for (int j = 0; j < win_size; j++) { blk_img[i*win_size + j] = blk_expanded_cols->at<double>(i + 1, j + 1); } } downSampling(blk_img, win_size, high_freq_mat, flag); power[k + 1] = calcuPower(high_freq_mat, win_size); } } if (flag == 2) { Mat* blk_img_T = new Mat(); blk_img_T->create(win_size, win_size, CV_64FC1); //图像直接转置 for (int i = 0; i < win_size; i++) { for (int j = 0; j < win_size; j++) { blk_img_T->at<double>(i, j) = blk_mat_img->at<double>(j, i); } } for (int k = -1; k < 2; k++) { //循环之前,需要将blk_mat_img的数据重新赋值给blk_expanded,并填充边框 copyMakeBorder(*blk_img_T, *blk_expanded_rows, 1, 1, 0, 0, BORDER_REFLECT_101); copyMakeBorder(*blk_expanded_rows, *blk_expanded_cols, 0, 0, 1, 1, BORDER_REFLECT); //数据准备完毕,进行方向预测 for (int i = 1; i < win_size + 1; i = i + 2) { for (int j = 1; j < win_size + 1; j++) { blk_expanded_cols->at<double>(i, j) = blk_expanded_cols->at<double>(i, j) - 0.5*(blk_expanded_cols->at<double>(i - 1, j + k) + blk_expanded_cols->at<double>(i + 1, j - k)); } } for (int i = 0; i < win_size; i++) { for (int j = 0; j < win_size; j++) { blk_img[i*win_size + j] = blk_expanded_cols->at<double>(i + 1, j + 1); } } downSampling(blk_img, win_size, high_freq_mat, 1); power[k + 1] = calcuPower(high_freq_mat, win_size); } delete blk_img_T; } int dir = 0; dir = minIdx(power, 3) - 1; delete[] high_freq_mat; delete blk_mat_img; delete blk_expanded_rows; delete blk_expanded_cols; return dir;}

下面是方向小波核心程序

void singleLifting(Mat* img, int flag, int step, double coe, int* dir_mat){ /*小波变换单步提升,核心步骤 输入: img:输入图像 Mat* flag: 行列处理标志 flag == 1列变换, flag ==2 行变换 step: 小波处理步骤标志 step == 1预测 step == 2更新 coe:小波提升系数 dir_mat: 方向矩阵,大小与输入图像一致 输出: img: 输出图像,在函数内部对图像进行处理 */ int rows = img->size().height; int cols = img->size().width; if (flag == 1)//列变换 { //预处理,图像对称延拓一圈 Mat *extend_img = new Mat(); extend_img->create(rows + 1, cols + 1, CV_64FC1); copyMakeBorder(*img, *extend_img, 1, 1, 1, 1, BORDER_REFLECT_101); int extend_rows = extend_img->size().height; int extend_cols = extend_img->size().width; //第一步,确认输入数据的正确性 //输出扩展后的图像数据和进行预测的方向矩阵 if (step == 1)//预测 { for (int i = 1; i < extend_rows - 2; i = i + 2)//剔除原图最后一行,再2:2:rows-1 { for (int j = 1; j < extend_cols - 1; j++)//2:cols-1 { extend_img->at<double>(i, j) = extend_img->at<double>(i, j) + coe*( extend_img->at<double>(i - 1, j + dir_mat[(i - 1)*cols + j - 1]) + extend_img->at<double>(i + 1, j - dir_mat[(i - 1)*cols + j - 1]) ); } } for (int i = 0; i < rows; i++) { for (int j = 0; j < cols ; j++) { img->at<double>(i, j) = extend_img->at<double>(i + 1, j + 1); } } delete extend_img; } if (step == 2)//更新 { for (int i = 2; i < extend_rows - 1; i = i + 2)//剔除原图第一行,再2:2:rows-1 { for (int j = 1; j < extend_cols - 1; j++)//2:cols-1 { extend_img->at<double>(i, j) = extend_img->at<double>(i, j) + coe*(extend_img->at<double>(i - 1, j + dir_mat[(i - 1)*cols + j - 1]) + extend_img->at<double>(i + 1, j - dir_mat[(i - 1)*cols + j - 1])); } } for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { img->at<double>(i, j) = extend_img->at<double>(i + 1, j + 1); //outFile << img->at<double>(i, j) << endl; } } delete extend_img; } } if (flag == 2)//行变换 { Mat* img_T = new Mat(); img_T->create(cols, rows, CV_64FC1); int* dir_mat_T = new int[rows*cols]; for (int i = 0; i < cols; i++) { for (int j = 0; j < rows; j++) { img_T->at<double>(i, j) = img->at<double>(j, i); } } ////cvTranspose这一opencv内置函数用于矩阵的转置 matTrans(dir_mat, dir_mat_T, rows, cols); ////预处理,图像对称延拓一圈 Mat *extend_img = new Mat(); extend_img->create(rows + 1, cols + 1, CV_64FC1); copyMakeBorder(*img_T, *extend_img, 1, 1, 1, 1, BORDER_REFLECT_101); int extend_rows = extend_img->size().height; int extend_cols = extend_img->size().width; if (step == 1) { for (int i = 1; i < extend_rows - 2; i = i + 2)//剔除原图最后一行,再2:2:rows-1 { for (int j = 1; j < extend_cols - 1; j++)//2:cols-1 { extend_img->at<double>(i, j) = extend_img->at<double>(i, j) + coe*(extend_img->at<double>(i - 1, j + dir_mat_T[(i - 1)*rows + j - 1]) + extend_img->at<double>(i + 1, j - dir_mat_T[(i - 1)*rows + j - 1])); //此时的dir_mat_T是cols行,rows列 } } for (int i = 0; i < cols; i++) { for (int j = 0; j < rows; j++) { img_T->at<double>(i, j) = extend_img->at<double>(i + 1, j + 1); } } //将图像转置回去 //cvTranspose(img_T, img); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { img->at<double>(i, j) = img_T->at<double>(j, i); } } delete extend_img; delete img_T; delete[] dir_mat_T; } if (step == 2) { for (int i = 2; i < extend_rows - 1; i = i + 2)//剔除原图第一行,再2:2:rows-1 { for (int j = 1; j < extend_cols - 1; j++)//2:cols-1 { //extend_img[i*extend_cols + j] = extend_img[i*extend_cols + j] extend_img->at<double>(i, j) = extend_img->at<double>(i, j) + coe*(extend_img->at<double>(i - 1, j + dir_mat_T[(i - 1)*rows + j - 1]) + extend_img->at<double>(i + 1, j - dir_mat_T[(i - 1)*rows + j - 1])); } } for (int i = 0; i < cols; i++) { for (int j = 0; j < rows; j++) { img_T->at<double>(i, j) = extend_img->at<double>(i + 1, j + 1); } } //将图像转置回去 //cvTranspose(img_T, img); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { img->at<double>(i, j) = img_T->at<double>(j, i); } } delete extend_img; delete img_T; delete[] dir_mat_T; } }}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表