I'm implementing a very basic forward and inverse DWT, based on Mallat's book. Nothing fancy, simple inefficient matlab code (proof-of-concept more than runtime necessary, so I'm not focusing on optimisation). It almost works. I'm getting a distortion along the top and left edges. I'll post link to (need 10 points to post) some pictures of lichtenstein to exhibit the behaviour.

From top-to-bottom:
* After 5 iterations.
* After some unpacking iterations, you can see the distortion along the top and left edges growing.
* Unpacked and distorted.

I'm using symmetric boundary conditions (I've implemented both whole and half, it doesn't make much of a difference) and Haar. Although using CDF has the same effect (the distortion is a little different, but same location along the entire edge). Since the rest of the picture is transformed and inverted perfectly, there is most likely nothing wrong with the implementation as a whole. It must be some kind of index offset. It is clear that the expansion of the distortion is dyadic - it doubles in size for every step of the inverse loop. Two days and lots of index changing has led to no breakthroughs.

I've pasted the code here (I realise it's unlikely people will want to preuse 100 lines of foreign code, but I'm a little desperate). It's pretty simple to run (although like I said it's slow - can take up to a minute to run):

runbackward(runforward(rgb2gray(imread('lichtenstein.png')), 5),5)

Any code-based help or high-level diagnostic ideas would be appreciated.

  • 1
    $\begingroup$ It was an index issue. I've expanded in an answer, but I can't post it for 8 hours according to the rules of this site, or delete the question. So... $\endgroup$
    – Bjorne
    Jun 17 '13 at 14:58

Bjorne, I am not exactly sure what you are trying to do but I can assure you that the simplest of DWT code is not more than 10 lines in Matlab. Here is how to do it:

approx = zeros(1, cols);
details = zeros(1, cols);

%for Haar Wavelet, Use filterbanks in Matlab, google it!

hi = ...
lo = ...

for i = 1: Level

   a = conv2(signal, lo);
   d = conv2(signal, hi);

   detail() =  downsample(d);
   approx() =  downsample(a);
   signal = downsample(a);


That is pretty much everything you need to compute DWT. As for the values between the parenthesis in detail and approximation, just fill in the indexes.

  • $\begingroup$ Thanks. But I implemented a 2D DWT, along with the inverse, and symmetrical border conditions (none of which you implemented) so it's a bit more code :) $\endgroup$
    – Bjorne
    Jun 18 '13 at 9:11
  • $\begingroup$ I tried upvoting because this answer is still good, but I don't have the privilege to upvote... $\endgroup$
    – Bjorne
    Jun 18 '13 at 9:12
  • $\begingroup$ That is weird. Please do check again! $\endgroup$ Jun 18 '13 at 10:47
  • $\begingroup$ Nope. It isn't letting me. $\endgroup$
    – Bjorne
    Jun 18 '13 at 10:50

The problem was indeed indexing. Since matlab indexes things "mathematically" from 1, there's some disparity to the formulae that were zero-indexed. Some plus ones here and minus ones there sorted things out.

I'm answering instead of just deleting the post for reasons of posterity. Without going through the code the problem could have been diagnosed to something along these lines, since like I said, the problem couldn't have been totally fundamental to the implementation because it was mostly successful. Moreover, it was likely not related to border conditions, since only two of the four borders were affected. Interestingly that distortion pattern was purely index-related.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.