Why differnce coeffs size? (Wavelets transform)

hix: <p>This is my wavelets transform code</p>
<p>But I have some problems<br>
ValueError<br>
<code>coeffs</code> must all be of equal size (or None)<br>
File “/home/mars/workspace/cy_workspace/vscode/pywavelets/py.py”, line 21, in <br>
coeffs_u_5 = pywt.idwt2((coeffs_u_4,coeffs_d_2[1]),‘db3’)</p>
<p>coeffs_u_5 have a difference size error<br>
Why coeffs_u_4 difference size coeffs_d_2 please tell me solution Thank you</p>
<p>coeffs_d_2[1][1].size:4489<br>
coeffs_u_4.size:4624<br>
import pywt</p>
<pre><code>import pywt.data

import cv2

import torch

import numpy as np

import matplotlib.pyplot as plt

original = cv2.imread('/home/mars/workspace/cy_workspace/vscode/pywavelets/123.png',cv2.IMRE 
AD_GRAYSCALE)

coeffs_d_1 = pywt.dwt2(original,'db3')

coeffs_d_2 = pywt.dwt2(coeffs_d_1[0],'db3')

coeffs_d_3 = pywt.dwt2(coeffs_d_2[0],'db3')

coeffs_d_4 = pywt.dwt2(coeffs_d_3[0],'db3')

coeffs_d_5 = pywt.dwt2(coeffs_d_4[0],'db3')

coeffs_d_6 = pywt.dwt2(coeffs_d_5[0],'db3')

coeffs_u_1 = pywt.idwt2((np.empty(coeffs_d_6[0].shape),coeffs_d_6[1]),'db3')

coeffs_u_2 = pywt.idwt2((coeffs_u_1,coeffs_d_5[1]),'db3')

coeffs_u_3 = pywt.idwt2((coeffs_u_2,coeffs_d_4[1]),'db3')

coeffs_u_4 = pywt.idwt2((coeffs_u_3,coeffs_d_3[1]),'db3')

coeffs_u_5 = pywt.idwt2((coeffs_u_4,coeffs_d_2[1]),'db3') &lt;&lt; This Line have an error

coeffs_u_6 = pywt.idwt2((coeffs_u_5,coeffs_d_1[1]),'db3')

plt.imshow(coeffs_u_6,cmap='gray')

plt.show()</code></pre>

Alaqian: <p>You’ve got your answer right there:<br>
<code>coeffs_d_2[1][1].size</code>:4489<br>
<code>coeffs_u_4.size</code>:4624</p>
<p>This happens when you end up with non-integer dimensions when downsampling, and pywt.dwt2 rounds it up.<br>
for example, you have an image and <code>data.shape = (250, 400)</code>.</p>
<p><code>cA1, (cH1, cV1, cD1) = pywt.dwt2(data, 'haar')</code> &lt;&lt; <code>cA1.shape = (125, 200)</code><br>
<code>cA2, (cH2, cV2, cD2) = pywt.dwt2(CA1, 'haar')</code> &lt;&lt; <code>cA2.shape = (63, 100)</code></p>
<p><code>ca1 =  pywt.dwt2((cA2, (cH2, cV2, cD2)), 'haar')</code> &gt;&gt; <code>ca1.shape = (126, 200)</code><br>
<code>data2=  pywt.dwt2((ca1, (cH1, cV1, cD1)), 'haar')</code> &gt;&gt; <code>ca1.shape = (126, 200)</code>, ‘<code>cA1.shape = cH1.shape = cv1.shape = cD1.shape = (125, 200)</code>’</p>
<p>pywt.idwt2 does not like different dimensions of coefficients. I am not familiar with ‘db3’ but I tried your code with an image of shape <code>(760, 680)</code> and printed .shape of the coefficients:</p>
<p>Link to my notebook: <a href="https://github.com/Alaqian/PyWavelets-idtw2-error/blob/main/pywt-idwt2-error.ipynb" class="inline-onebox-loading" rel="noopener nofollow ugc">https://github.com/Alaqian/PyWavelets-idtw2-error/blob/main/pywt-idwt2-error.ipynb</a></p>
<p><strong>Code:</strong></p>
<pre><code class="lang-auto">import pywt.data

import cv2

import numpy as np

import matplotlib.pyplot as plt

original = cv2.imread('gigachad.jpg',cv2.IMREAD_GRAYSCALE)
print(original.shape)

coeffs_d_1 = pywt.dwt2(original,'db3')
print(f"coeffs_d_1[1][1].shape = {coeffs_d_1[1][1].shape}")
coeffs_d_2 = pywt.dwt2(coeffs_d_1[0],'db3')
print(f"coeffs_d_2[1][1].shape = {coeffs_d_2[1][1].shape}")
coeffs_d_3 = pywt.dwt2(coeffs_d_2[0],'db3')
print(f"coeffs_d_3[1][1].shape = {coeffs_d_3[1][1].shape}")
coeffs_d_4 = pywt.dwt2(coeffs_d_3[0],'db3')
print(f"coeffs_d_4[1][1].shape = {coeffs_d_4[1][1].shape}")
coeffs_d_5 = pywt.dwt2(coeffs_d_4[0],'db3')
print(f"coeffs_d_5[1][1].shape = {coeffs_d_5[1][1].shape}")
coeffs_d_6 = pywt.dwt2(coeffs_d_5[0],'db3')
print(f"coeffs_d_6[1][1].shape = {coeffs_d_6[1][1].shape}")

coeffs_u_1 = pywt.idwt2((np.empty(coeffs_d_6[0].shape),coeffs_d_6[1]),'db3')
print(f"coeffs_u_1.shape = {coeffs_u_1.shape}")
coeffs_u_2 = pywt.idwt2((coeffs_u_1,coeffs_d_5[1]),'db3')
print(f"coeffs_u_2.shape = {coeffs_u_2.shape}")
coeffs_u_3 = pywt.idwt2((coeffs_u_2,coeffs_d_4[1]),'db3')
print(f"coeffs_u_3.shape = {coeffs_u_3.shape}")
</code></pre>
<p><strong>Output:</strong></p>
<blockquote>
<h2>original.shape = (760, 680)<br>
coeffs_d_1[1][1].shape = (382, 342)<br>
coeffs_d_2[1][1].shape = (193, 173)<br>
coeffs_d_3[1][1].shape = (99, 89)<br>
coeffs_d_4[1][1].shape = (52, 47)<br>
coeffs_d_5[1][1].shape = (28, 26)<br>
coeffs_d_6[1][1].shape = (16, 15)<br>
coeffs_u_1.shape = (28, 26)<br>
coeffs_u_2.shape = (52, 48)</h2>
<p>ValueError                                Traceback (most recent call last)<br>
Cell In[6], line 29<br>
27 coeffs_u_2 = pywt.idwt2((coeffs_u_1,coeffs_d_5[1]),‘db3’)<br>
28 print(f"coeffs_u_2.shape = {coeffs_u_2.shape}“)<br>
—&gt; 29 coeffs_u_3 = pywt.idwt2((coeffs_u_2,coeffs_d_4[1]),‘db3’)<br>
30 print(f"coeffs_u_3.shape = {coeffs_u_3.shape}”)<br>
31 coeffs_u_4 = pywt.idwt2((coeffs_u_3,coeffs_d_3[1]),‘db3’)</p>
<p>File ~\miniconda3\envs\ImV\lib\site-packages\pywt_multidim.py:118, in idwt2(coeffs, wavelet, mode, axes)<br>
115     raise ValueError(“Expected 2 axes”)<br>
117 coeffs = {‘aa’: LL, ‘da’: HL, ‘ad’: LH, ‘dd’: HH}<br>
 → 118 return idwtn(coeffs, wavelet, mode, axes)</p>
<p>File ~\miniconda3\envs\ImV\lib\site-packages\pywt_multidim.py:280, in idwtn(coeffs, wavelet, mode, axes)<br>
277     raise ValueError("<code>coeffs</code> must contain at least one non-null wavelet "<br>
278                      “band”)<br>
279 if any(s != coeff_shape for s in coeff_shapes):<br>
 → 280     raise ValueError(“<code>coeffs</code> must all be of equal size (or None)”)<br>
282 if axes is None:<br>
283     axes = range(ndim_transform)</p>
<p>ValueError: <code>coeffs</code> must all be of equal size (or None)</p>
</blockquote>
<p>So <code>coeffs_d_4[1][1].shape = (52, 47)</code>  and <code>coeffs_u_2.shape = (52, 48)</code> which idwt2 does not know how to deal with.<br>
One solution is to check the dimensions of the coefficients and truncate the first row using <code>coeffs_u_2[1:, :]</code> but I am not a fan of this solution and the reconstruction results are poorer. The solution that worked for me using ‘haar’ was cropping the original image so that it is a multiple of <code>2 ** d</code>, where d is the level of decomposition. In your case, <code>d = 6</code>, so your dimensions should be a multiple of <code>2**6 = 64</code> if you are using <code>haar</code>, but <code>db3</code> works differently.</p>
<p>Hope this helps!</p>
<p>More information on this thread: <a href="https://github.com/PyWavelets/pywt/issues/54" class="inline-onebox-loading" rel="noopener nofollow ugc">https://github.com/PyWavelets/pywt/issues/54</a></p>