Реализация DWT не работает, что не так?

Я реализовал 2D дискретное вейвлет-преобразование из javacode (см. Вот).
Когда я выполняю оригинальный код в Java, результат выглядит хорошо. Но в моей реализации C ++ результат искажен. Я не знаю почему (см. Рисунок).
Оригинальное изображение:
оригинальное изображение
не удалось dwt:
DWT Dailure

Это проблема из-за преобразования между матом opencv и массивом?
Или это ошибка в реализации dwt?

main.cpp

#include <math.h>
#include "dwt_cdf_9_7.h"#include "dwt.c";
#include "opencv/cv.h";

void analyze(cv::Mat img) {
int cols = img.cols;
int rows = img.rows;
/* convert image to grayscale */
cv::Mat gray8 = cv::Mat(rows, cols, CV_8UC1);
cv::cvtColor(img, gray8, CV_BGR2GRAY);

/* resize */
if(rows % 2 != 0 || cols % 2 != 0) {
rows -= rows%8;
cols -= cols%8;
cv::Size s = cv::Size(rows, cols);
cv::Mat resized = cv::Mat(s, CV_8UC1);
cv::resize(gray8, resized, s);
gray8=resized;
}
cv::Mat gray32 = cv::Mat(cols, rows, CV_32FC1);
gray8.convertTo(gray32, CV_32FC1);
//reshape image
cv::Mat reshape = gray32.reshape ( 0, 1 );
std::vector<float> v_float(reshape.begin<float>(), reshape.end<float>());
std::vector<int> v_int(v_float.begin(), v_float.end());
int* block= v_int.data();
//get dwt
DWT_CDF_9_7 dwt(cols,rows,3);
block=dwt.forward(block,0);
std::vector<float> v_float2(v_int.begin(), v_int.end());
float* block2= &v_float2[0];
cv::Mat dwt_reshaped(cols,rows,CV_32FC1,v_float2.data());
cv::normalize(dwt_reshaped, dwt_reshaped, 0, 255, CV_MINMAX);
imwrite("res.jpg",dwt_reshaped);
}

dwt_cdf_9_7.h

 #ifndef DWT_CDF_9_7_H
#define DWT_CDF_9_7_H

class DWT_CDF_9_7
{
public:
DWT_CDF_9_7(int dim);
DWT_CDF_9_7(int width, int height);
DWT_CDF_9_7(int width, int height, int steps);

int *data;
int width;
int height;
int steps;

int* forward(int block[], int blkptr);
int* inverse(int block[], int blkptr);

private:
static const int SHIFT  = 12;
static const int ADJUST = 1 << (SHIFT - 1);

static const int PREDICT_1 = 6497; // with SHIFT = 12
static const int UPDATE_1  = 217;  // with SHIFT = 12
static const int PREDICT_2 = 3616; // with SHIFT = 12
static const int UPDATE_2  = 1817; // with SHIFT = 12
static const int SCALING_1 = 4709; // with SHIFT = 12
static const int SCALING_2 = 3562; // with SHIFT = 12int* forward(int block[], int blkptr, int stride, int inc, int dim1, int dim2);
int* inverse(int block[], int blkptr, int stride, int inc, int dim1, int dim2);
};
#endif // DWT_CDF_9_7_H

dwt_cdf_9_7.cpp

 #include <stdlib.h>
#include "dwt_cdf_9_7.h"DWT_CDF_9_7::DWT_CDF_9_7(int width, int height, int steps)
{
this->width = width;
this->height = height;
this->steps = steps;
this->data = (int*) malloc(sizeof(int)*width*height);
}

int* DWT_CDF_9_7::forward(int block[], int blkptr) {
for (int i=0; i<this->steps; i++) {
/* vertical transform */
block = forward(block, blkptr, this->width, 1, this->width>>i, this->height>>i);

/* horizontal transform */
block = forward(block, blkptr, 1, this->width, this->height>>i, this->width>>i);
}

return block;
}

int* DWT_CDF_9_7::forward(int block[], int blkptr, int stride, int inc, int dim1, int dim2) {
{
int stride2 = stride << 1;
int endOffs = blkptr + (dim1 * inc);
int half = stride * (dim2  >> 1);

for (int offset=blkptr; offset<endOffs; offset+=inc)
{
int end = offset + (dim2 - 2) * stride;
long tmp;
int prev = block[offset];

// First lifting stage : Predict 1
for (int i=offset+stride; i<end; i+=stride2)
{
int next = block[i+stride];
tmp = (PREDICT_1 * (prev + next));
block[i] -= ((tmp + ADJUST) >> SHIFT);
prev = next;
}

tmp = PREDICT_1 * block[end] ;
block[end+stride] -= (((tmp + tmp) + ADJUST) >> SHIFT);
prev = block[offset+stride];

// Second lifting stage : Update 1
for (int i=offset+stride2; i<=end; i+=stride2)
{
int next = block[i+stride];
tmp = UPDATE_1 * (prev + next);
block[i] -= ((tmp + ADJUST) >> SHIFT);
prev = next;
}

tmp = UPDATE_1 * block[offset+stride];
block[offset] -= (((tmp + tmp) + ADJUST) >> SHIFT);
prev = block[offset];

// Third lifting stage : Predict 2
for (int i=offset+stride; i<end; i+=stride2)
{
int next = block[i+stride];
tmp = PREDICT_2 * (prev + next);
block[i] += ((tmp + ADJUST) >> SHIFT);
prev = next;
}

tmp = PREDICT_2 * block[end];
block[end+stride] += (((tmp + tmp) + ADJUST) >> SHIFT);
prev = block[offset+stride];

// Fourth lifting stage : Update 2
for (int i=offset+stride2; i<=end; i+=stride2)
{
int next = block[i+stride];
tmp = (UPDATE_2 * (prev + next));
block[i] += ((tmp + ADJUST) >> SHIFT);
prev = next;
}

tmp = UPDATE_2 * block[offset+stride];
block[offset] += (((tmp + tmp) + ADJUST) >> SHIFT);

// Scale
for (int i=offset; i<=end; i+=stride2)
{
tmp = block[i] * SCALING_1;
block[i] = (int) ((tmp + ADJUST) >> SHIFT);
tmp = block[i+stride] * SCALING_2;
block[i+stride] = (int) ((tmp + ADJUST) >> SHIFT);
}

// De-interleave sub-bands
int endj = offset + half;

for (int i=offset, j=offset; j<endj; i+=stride2, j+=stride)
{
this->data[j] = block[i];
this->data[half+j] = block[i+stride];
}

block[end+stride] = this->data[end+stride];

for (int i=offset; i<=end; i+=stride)
block[i] = this->data[i];
}

return block;
}
}

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector