In the literature, I see that a 2D signal can be transformed by first doing a 1D transformation on each row of the matrix followed by the same procedure on each column. It seems that $k^{th}$ level end up with $depth - k$ copies squished into the HL and LH bands when $depth>k$. Clearly I'm doing something wrong--any insight would be appreciated.
I'm using Haar filters, so the boundary thing isn't a problem (I'm not padding yet).
Also note that the transformation isn't normalized so that it's easier to see the issue. The LL band looks correct.
void dwt1D(Mat mat, Mat h, Mat g, int depth) {
int numCoefficients = g.cols;
int size = mat.cols;
Mat t = mat.clone();
Mat y = Mat::zeros(mat.rows, mat.cols, mat.type());
for (int i = 0; i < depth; i++) {
y(Rect(0,0,size,1)).setTo(Scalar(0));
int halfSize = size >> 1;
for (int j = 0; j < halfSize; j++) {
for (int k = 0; k < numCoefficients; k++) {
y.at(j) += t.at(2*j+k) * h.at(k);
y.at(j+halfSize) += t.at(2*j+k) * g.at(k);
}
}
size = halfSize;
y(Rect(0,0,size,1)).copyTo(t(Rect(0,0,size,1)));
}
y.copyTo(mat);
}
cv::Mat dwt(cv::Mat mat, Mat h, Mat g, int depth) {
mat = mat.t();
for(int i = 0; i < mat.rows; i++) {
dwt1D(mat.row(i), h, g, depth);
}
mat = mat.t();
for(int i = 0; i < mat.rows; i++) {
dwt1D(mat.row(i), h, g, depth);
}
return mat;
}
Answer
Apparently, you are not doing wrong. You are doing a $k$-level transform on the rows, then on the columns. Giving you rectangular subband. This is fine, and is one of the modes of DWT in 2D. It is called non-separable, standard, anisotropic, and there is a bibliography in A panorama on Multiscale Geometric Representations (2D wavelets). The classic square decomposition applies one DWT level on the rows, one and the columns, and again...
The rectangular version is more common in partial differential equations, more computationally demanding, and could be more efficient for anisotropic images. The square version is much more common for standard images.
[EDIT: Added references to related questions]
No comments:
Post a Comment