Transform dataset to local binary pattern

VahidZarghami: <p>Hello guys</p>
<p>Here is my local binary pattern function:</p>
<blockquote>
<p>def lbp(x):</p>
<pre><code>imgUMat = np.float32(x)

gray = cv2.cvtColor(imgUMat, cv2.COLOR_RGB2GRAY)

radius = 2
n_points = 8 * radius

METHOD = 'uniform'
    
lbp = local_binary_pattern(gray, n_points, radius, METHOD)
lbp = torch.from_numpy(lbp).long()
    
return lbp
</code></pre>
</blockquote>
<p>Here I call lbp function:</p>
<blockquote>
<p>input_img = plt.imread(trn_fnames[31])<br>
x = lbp(input_img)</p>
</blockquote>
<p>When I use x.shape it is:</p>
<blockquote>
<p>torch.Size([600, 600])<br>
Sounds good!!!</p>
</blockquote>
<p>But my problem is when I use transforms.Lambda(lbp) in my transform function, my output image is torch.Size([600])</p>
<blockquote>
<p>tfms = transforms.Compose([</p>
<p>transforms.Lambda(lbp)])</p>
<p>train_ds = datasets.ImageFolder(trn_dir, transform = tfms)</p>
<p>(train_ds[0][0][0]).shape<br>
<strong>torch.Size([600])</strong>!!! &gt;&gt;&gt;&gt; my problem</p>
</blockquote>
<p><strong>I need torch.Size([600, 600])</strong></p>
<p>I also different ways such as this:</p>
<blockquote>
<p>tfms = transforms.Compose([</p>
<p>transforms.Lambda(lbp),<br>
transforms.ToPILImage(),<br>
transforms.Resize((sz, sz))])</p>
</blockquote>
<p>And I got this error:</p>
<blockquote>
<p>TypeError: pic should be Tensor or ndarray. Got &lt;class ‘torch.Tensor’&gt;.</p>
</blockquote>
<p>I also added</p>
<blockquote>
<p>transforms.ToTensor()])</p>
</blockquote>
<p>But still have the same error:</p>
<blockquote>
<p>TypeError: pic should be Tensor or ndarray. Got &lt;class ‘torch.Tensor’&gt;.</p>
</blockquote>
<p>I’ll appreciate to your comments please!<br>
Thank you.</p>

VahidZarghami: <p>Hi <a class="mention" href="/u/ptrblck">@ptrblck</a><br>
As always I hope you have some answers for me!<br>
You are a Hero in this website <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>

ptrblck: <p>The code seems to work correctly.<br>
This code snippet applies the transformation only:</p>
<pre><code class="lang-python">def lbp_transform(x):
    imgUMat = np.float32(x)
    lbp = imgUMat * 10 # fake transformation
    lbp = torch.from_numpy(lbp)
    return lbp

x = np.random.randn(600, 600)
out = lbp_transform(x)
print(out.shape)
&gt; torch.Size([600, 600])
</code></pre>
<p>while this snippet wraps it in a <code>torchvision.transforms.Compose</code> object:</p>
<pre><code class="lang-python">tfms = transforms.Compose([
    transforms.Lambda(lbp_transform),
    transforms.ToPILImage(),
    transforms.Resize((300, 300)),
    transforms.ToTensor()
])

out = tfms(x)
print(out.shape)
&gt; torch.Size([1, 300, 300])
</code></pre>
<p>Are you sure this indexing is correct and you are not in fact indexing into the <code>height</code> dimension?</p>
<pre><code class="lang-python">(train_ds[0][0][0]).shape
</code></pre>

VahidZarghami: <p>Thanks <a class="mention" href="/u/ptrblck">@ptrblck</a><br>
Your codes work correct but the problem is when I add Local Binary Pattern part in lbp_transfer function I get the error:</p>
<blockquote>
<p>from skimage.feature import local_binary_pattern</p>
</blockquote>
<blockquote>
<p>def lbp_transform(x):</p>
<pre><code>radius = 2
n_points = 8 * radius
METHOD = 'uniform'
imgUMat = np.float32(x)
gray = cv2.cvtColor(imgUMat, cv2.COLOR_RGB2GRAY)

**lbp = local_binary_pattern(gray, n_points, radius, METHOD)**
lbp = torch.from_numpy(lbp)
  
return lbp
</code></pre>
</blockquote>
<blockquote>
<p>tfms = transforms.Compose([</p>
</blockquote>
<blockquote>
<p>transforms.Lambda(lbp_transform),<br>
transforms.ToPILImage(),<br>
transforms.Resize((300, 300)),<br>
transforms.ToTensor()<br>
])</p>
</blockquote>
<blockquote>
<p>out = tfms(x)<br>
print(out.shape)</p>
</blockquote>
<p><strong>&gt; TypeError: pic should be Tensor or ndarray. Got &lt;class ‘torch.Tensor’&gt;.</strong><br>
My goal is convert all dataset images to texture images by using lbp, but I stocked in this step.</p>
<blockquote>
<p>(train_ds[0][0][0]).shape</p>
</blockquote>
<p>Shows my dataset image [0] shape, but if I use it by adding “print”, it shows me error,</p>

ptrblck: <p>I can’t reproduce this issue, and this code works fine on my machine:</p>
<pre><code class="lang-python">def lbp_transform(x):
    radius = 2
    n_points = 8 * radius
    METHOD = 'uniform'
    imgUMat = np.float32(x)
    gray = cv2.cvtColor(imgUMat, cv2.COLOR_RGB2GRAY)
    lbp = local_binary_pattern(gray, n_points, radius, METHOD)
    lbp = torch.from_numpy(lbp).float()
    return lbp


x = np.random.randn(600, 600, 3)
out = lbp_transform(x)
print(out.shape)
&gt; torch.Size([600, 600])

tfms = transforms.Compose([
    transforms.Lambda(lbp_transform),
    transforms.ToPILImage(),
    transforms.Resize((300, 300)),
    transforms.ToTensor()
])

out = tfms(x)
print(out.shape)
&gt; torch.Size([1, 300, 300])
</code></pre>
<p>Could you compare your code to my code snippet?</p>

VahidZarghami: <p>Thanks <a class="mention" href="/u/ptrblck">@ptrblck</a> the key part that you mentioned is “.float()” in:</p>
<blockquote>
<p><code>lbp = torch.from_numpy(lbp).float()</code></p>
</blockquote>
<p>After you said on your machine works fine, I thought the problem is my Jupyter Notebook because when I run it in IDLE python or Google colab I get the correct answer<br>
But when in the Jupyter Notebook I get this error:</p>
<blockquote>
<p>TypeError: pic should be Tensor or ndarray. Got &lt;class ‘torch.Tensor’&gt;.</p>
</blockquote>
<p>do you have any idea that works on Jupyter as well?</p>

ptrblck: <p>I guess you might be using different PyTorch and torchvision versions in your Jupyter environment and in your IDE, so you might need to check which Python kernel is executed.</p>

VahidZarghami: <p>I will check it.<br>
Thnak you <a class="mention" href="/u/ptrblck">@ptrblck</a></p>

saandeep_aathreya: <p>Hello, Extracting LBP generally (in the dataset class) seems like an expensive operation. Were you able to achieve good speed with the solution code?</p>