Region growing with the watershed transform error - image-processing

Hello guys I am new to image processing, I've been trying out this code from adfoucart but I have been receiving this error
https://github.com/adfoucart/image-processing-notebooks/blob/main/V31%20-%20Region%20growing%20with%20the%20watershed%20transform.ipynb
image.shape
(240, 320)
from skimage.filters import rank,gaussian
from skimage.morphology import disk
from skimage.feature import peak_local_max
def get_markers(image, indices=False):
im_ = gaussian(image, sigma=4)
gradr = rank.gradient(im_[:,:,0],disk(5)).astype('int')
gradg = rank.gradient(im_[:,:,1],disk(5)).astype('int')
gradb = rank.gradient(im_[:,:,2],disk(5)).astype('int')
grad = gradr+gradg+gradb
return peak_local_max(grad.max()-grad,threshold_rel=0.5, min_distance=60,indices=indices),grad
markers,grad = get_markers(image, True)
plt.figure()
plt.imshow(grad, cmap=plt.cm.gray)
plt.plot(markers[:,1],markers[:,0],'b+')
plt.show()
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
/var/folders/f9/5vh23mb50wj5wq4vfl8wcgx40000gn/T/ipykernel_34090/3084023926.py in <module>
12 return peak_local_max(grad.max()-grad,threshold_rel=0.5, min_distance=60,indices=indices),grad
13
---> 14 markers,grad = get_markers(image, True)
15 plt.figure()
16 plt.imshow(grad, cmap=plt.cm.gray)
/var/folders/f9/5vh23mb50wj5wq4vfl8wcgx40000gn/T/ipykernel_34090/3084023926.py in get_markers(image, indices)
5 def get_markers(image, indices=False):
6 im_ = gaussian(image, sigma=4)
----> 7 gradr = rank.gradient(im_[:,:,0],disk(5)).astype('int')
8 gradg = rank.gradient(im_[:,:,1],disk(5)).astype('int')
9 gradb = rank.gradient(im_[:,:,2],disk(5)).astype('int')
IndexError: too many indices for array: array is 2-dimensional, but 3 were indexed
Any help will be appreciated thank you so much!

Your image is greyscale, i.e. single channel. I can tell that because its shape is (240,320) rather than (240,320,3) which it would be if 3-channel RGB.
That means you don't need to average across 3 channels, and you should just use 2 indices, i.e.
grad = rank.gradient(im_[:,:],disk(5)).astype('int')
In fact, you can probably just use:
grad = rank.gradient(im_,disk(5)).astype('int')

Related

How do i fix this error TypeError: '>=' not supported between instances of 'int' and 'str'

I am trying and testing an outbreak prediction model; but I am facing an error:
TypeError Traceback (most recent call last)
Cell In [12], line 7
5 for i in [mea,mum,per,pol,rub,sma]:
6 train_data = train_data.append(i)
----> 7 train_data = train_data.loc[(train_data['Year'] >= '1960') & (train_data['Year'] <= '2011')]
9 # examine the dataset
10 train_data.head()
File c:\Users\Alkaejah\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\ops\common.py:72, in _unpack_zerodim_and_defer.<locals>.new_method(self, other)
68 return NotImplemented
70 other = item_from_zerodim(other)
---> 72 return method(self, other)
File c:\Users\Alkaejah\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\arraylike.py:62, in OpsMixin.__ge__(self, other)
60 #unpack_zerodim_and_defer("__ge__")
61 def __ge__(self, other):
---> 62 return self._cmp_method(other, operator.ge)
File c:\Users\Alkaejah\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\series.py:6243, in Series._cmp_method(self, other, op)
6240 rvalues = extract_array(other, extract_numpy=True, extract_range=True)
6242 with np.errstate(all="ignore"):
-> 6243 res_values = ops.comparison_op(lvalues, rvalues, op)
6245 return self._construct_result(res_values, name=res_name)
...
35 typ = type(right).__name__
---> 36 raise TypeError(f"Invalid comparison between dtype={left.dtype} and {typ}")
37 return res_values
TypeError: Invalid comparison between dtype=int64 and str
SOURCE CODE:
import warnings
warnings.filterwarnings("ignore")
import pandas as pd
import calendar
import numpy as np
def week2month(hep):
hep['LastDayWeek'] = pd.to_datetime((hep['week']-1).astype(str) + "6", format="%Y%U%w")
hep['MonthMax'] = pd.DatetimeIndex(hep['LastDayWeek']).month
hep['Year'] = pd.DatetimeIndex(hep['LastDayWeek']).year
hep['MonthName'] = [calendar.month_name[i] for i in hep.MonthMax]
def get_input_transform(file_):
return week2month(pd.read_csv(file_))
hep = get_input_transform('hepatitis.csv')
mea = get_input_transform('measles.csv')
mum = get_input_transform('mumps.csv')
per = get_input_transform('pertussis.csv')
pol = get_input_transform('polio.csv')
rub = get_input_transform('rubella.csv')
sma = get_input_transform('smallpox.csv')
train_data = hep
for i in [mea,mum,per,pol,rub,sma]:
train_data = train_data.append(i)
train_data = train_data.loc[(train_data['Year'] >= 1960) & (train_data['Year'] <=2011)]
train_data.head()
# some data discrepancies must be resolved (issues like \\N )
train_data_bad = train_data[train_data.cases==train_data.cases.max()]
ind = list(train_data_bad.index)
train_data = train_data.drop(train_data.index[ind])
I have tried different article to debug the code and this is a thesis related matter.

Create dataset from a folder of images and a txt file with labels

I have two folders containing train and test images. And I have two files train.txt and test.txt containing the labels. I want to create a dataset for a PyTorch setting. I mean, I want to use DataLoader and I want the tuples (x_train, y_train) and (x_test, y_test). How can I do? Basically I think that in tensorflow I can use flow_from_dataframe, but in PyTorch?
As an example, in this image I show my pandas dataframe containing filenames and labels:
EDIT:
I am trying with a custom dataset class:
from torch.utils.data import Dataset, DataLoader
import os
import pandas as pd
from torchvision.io import read_image
class CoViDxDataset(Dataset):
def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
self.img_labels = annotations_file
self.img_dir = img_dir
self.transform = transform
self.target_transform = target_transform
def __len__(self):
return len(self.img_labels)
def __getitem__(self, idx):
img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
print(img_path)
image = read_image(img_path)
label = self.img_labels.iloc[idx, 1]
if self.transform:
image = self.transform(image)
if self.target_transform:
label = self.target_transform(label)
return image, label
train_dataset = CoViDxDataset(train_df, train_path)
When I do train_dataset[0] I have this error:
train/ARDSSevere.png
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Input In [84], in <cell line: 1>()
----> 1 train_dataset[0]
Input In [82], in CoViDxDataset.__getitem__(self, idx)
17 img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
18 print(img_path)
---> 19 image = read_image(img_path)
20 label = self.img_labels.iloc[idx, 1]
21 if self.transform:
File ~/anaconda3/envs/openfl/lib/python3.8/site-packages/torchvision/io/image.py:245, in read_image(path, mode)
243 if not torch.jit.is_scripting() and not torch.jit.is_tracing():
244 _log_api_usage_once(read_image)
--> 245 data = read_file(path)
246 return decode_image(data, mode)
File ~/anaconda3/envs/openfl/lib/python3.8/site-packages/torchvision/io/image.py:47, in read_file(path)
45 if not torch.jit.is_scripting() and not torch.jit.is_tracing():
46 _log_api_usage_once(read_file)
---> 47 data = torch.ops.image.read_file(path)
48 return data
RuntimeError: Expected a non empty file
where train_path = 'train/' and train_df is the image below:

RuntimeError: output with shape [512] doesn't match the broadcast shape [1, 512, 1, 512] while extracting feature vector using pytorch

I am not able to resolve this error. This code is taken from https://becominghuman.ai/extract-a-feature-vector-for-any-image-with-pytorch-9717561d1d4c
import torch
import torch.nn as nn
import torchvision.models as models
import torchvision.transforms as transforms
from torch.autograd import Variable
from PIL import Image
pic_one = '/content/drive/My Drive/Video_Recommender/zframe1.jpg'
pic_two = '/content/drive/My Drive/Video_Recommender/zframe2.jpg'
model = models.resnet18(pretrained=True)
layer = model._modules.get('avgpool')
scaler = transforms.Scale((224, 224))
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
to_tensor = transforms.ToTensor()
def get_vector(image_name):
# 1. Load the image with Pillow library
img = Image.open(image_name)
# 2. Create a PyTorch Variable with the transformed image
t_img = Variable(normalize(to_tensor(scaler(img))).unsqueeze(0))
# 3. Create a vector of zeros that will hold our feature vector
# The 'avgpool' layer has an output size of 512
my_embedding = torch.zeros(512)
# 4. Define a function that will copy the output of a layer
def copy_data(m, i, o):
my_embedding.copy_(o.data)
# 5. Attach that function to our selected layer
h = layer.register_forward_hook(copy_data)
# 6. Run the model on our transformed image
model(t_img)
# 7. Detach our copy function from the layer
h.remove()
# 8. Return the feature vector
return my_embedding
pic_one_vector = get_vector(pic_one)
pic_two_vector = get_vector(pic_two)
Error:-
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-41-ca2d66de2d9c> in <module>()
----> 1 pic_one_vector = get_vector(pic_one)
2 pic_two_vector = get_vector(pic_two)
5 frames
<ipython-input-40-a45affe9d8f7> in get_vector(image_name)
13 h = layer.register_forward_hook(copy_data)
14 # 6. Run the model on our transformed image
---> 15 model(t_img)
16 # 7. Detach our copy function from the layer
17 h.remove()
/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
548 result = self._slow_forward(*input, **kwargs)
549 else:
--> 550 result = self.forward(*input, **kwargs)
551 for hook in self._forward_hooks.values():
552 hook_result = hook(self, input, result)
/usr/local/lib/python3.6/dist-packages/torchvision/models/resnet.py in forward(self, x)
218
219 def forward(self, x):
--> 220 return self._forward_impl(x)
221
222
/usr/local/lib/python3.6/dist-packages/torchvision/models/resnet.py in _forward_impl(self, x)
211 x = self.layer4(x)
212
--> 213 x = self.avgpool(x)
214 x = torch.flatten(x, 1)
215 x = self.fc(x)
/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
550 result = self.forward(*input, **kwargs)
551 for hook in self._forward_hooks.values():
--> 552 hook_result = hook(self, input, result)
553 if hook_result is not None:
554 result = hook_result
<ipython-input-40-a45affe9d8f7> in copy_data(m, i, o)
9 # 4. Define a function that will copy the output of a layer
10 def copy_data(m, i, o):
---> 11 my_embedding.copy_(o.data)
12 # 5. Attach that function to our selected layer
13 h = layer.register_forward_hook(copy_data)
RuntimeError: output with shape [512] doesn't match the broadcast shape [1, 512, 1, 512]
What I am actually trying to do is trying to extract feature vector from images that I want to further use for building a recommendation system. Do inform me if there is any other alternative available.
Thanks in advance!!!
You need to reshape the output data after avgpool:
def copy_data(m, i, o):
my_embedding.copy_(o.data.reshape(o.data.size(1)))
Alternatively, you may replace the hook function with the following, just so you don't have to deal with adjusting the output shape:
# step 3 and 4
my_embedding = None
def my_hook(module_, input_, output_):
nonlocal my_output
my_embedding = output_
then simply call the following
# step 5
h = layer.register_forward_hook(my_hook)

How to use custom image loader for DataGenerator keras?

I'm trying to use a custom preprocessing function that uses OpenCV but there's a mismatch between the image loaded by the DataGenerator and the CV2 default type.
Is it possible to specify which function to use to load images?
Here is my code.
def read_and_process_image(im,im_size):
#read image from file
#im=cv2.imread(im)
gray = cv2.cvtColor(im,cv2.COLOR_RGB2GRAY) # convert 2 grayscale
im_pil = Image.fromarray(gray)
_,thresh = cv2.threshold(gray,10,255,cv2.THRESH_BINARY) # turn it into a binary image
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) # find contours
if len(contours) != 0:
print("contour")
#find the biggest area
cnt = max(contours, key = cv2.contourArea)
#find the bounding rect
x,y,w,h = cv2.boundingRect(cnt)
r=int(w*0.12)
crop = im[y+r:y+h-r,x+r:x+w-r]# crop image
crop=cv2.flip(crop,40)
#crop1=cv2.resize(crop,(im_size,im_size))
# resize to im_size X im_size size
#crop1 = cv2.convertScaleAbs(crop, alpha=1, beta=0.0001)
crop1=normalize_histograms(crop)
#clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
#crop1 = clahe.apply(crop1)
return crop1
else:
return( normalize_histograms(cv2.resize(im,(im_size,im_size))) )
the preprocessing function to call:
IM_SIZE=256
def preprocessing_image(image):
global IM_SIZE
image=read_and_process_image(image,IM_SIZE)
return image
and the DataGenerator:
train_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1./255,
featurewise_center=True,
featurewise_std_normalization=True,
preprocessing_function=preprocessing_image)
val_gen = train_datagen.flow_from_dataframe(dataframe=val_data,
directory="D:/PROJECTS/MLPC2019/dataset/train/train",
x_col="filename",
y_col="label",
class_mode="categorical",
shuffle=False,
target_size=(IMAGE_SIZE,IMAGE_SIZE),
batch_size=BATCH_SIZE)
plt.imshow(val_gen[0])
I get the following error:
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-130-c8fee3202272> in <module>
----> 1 plt.imshow(val_gen[0])
~\Anaconda3\lib\site-packages\keras_preprocessing\image\iterator.py in __getitem__(self, idx)
63 index_array = self.index_array[self.batch_size * idx:
64 self.batch_size * (idx + 1)]
---> 65 return self._get_batches_of_transformed_samples(index_array)
66
67 def __len__(self):
~\Anaconda3\lib\site-packages\keras_preprocessing\image\iterator.py in _get_batches_of_transformed_samples(self, index_array)
237 params = self.image_data_generator.get_random_transform(x.shape)
238 x = self.image_data_generator.apply_transform(x, params)
--> 239 x = self.image_data_generator.standardize(x)
240 batch_x[i] = x
241 # optionally save augmented images to disk for debugging purposes
~\Anaconda3\lib\site-packages\keras_preprocessing\image\image_data_generator.py in standardize(self, x)
702 """
703 if self.preprocessing_function:
--> 704 x = self.preprocessing_function(x)
705 if self.rescale:
706 x *= self.rescale
<ipython-input-101-3a910a8620ec> in preprocessing_image(image)
15 """
16 # TODO: augment more here
---> 17 image=read_and_process_image(image,IM_SIZE)
18 return image
<ipython-input-128-aa711687f072> in read_and_process_image(im, im_size)
8 im_pil = Image.fromarray(gray)
9 _,thresh = cv2.threshold(gray,10,255,cv2.THRESH_BINARY) # turn it into a binary image
---> 10 contours,hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) # find contours
11
12 if len(contours) != 0:
error: OpenCV(4.1.2) C:\projects\opencv-python\opencv\modules\imgproc\src\contours.cpp:197: error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function 'cvStartFindContours_Impl'
A cv2 image is nothing but a numpy array.
You can easily transform a PIL image (Keras) into a cv2 image by simply calling cv2_image = np.array(pil_image).
Since cv2 works with BGR instead of RGB, you may call cv2_image = np.flip(cv2_image, axis=-1) (if there are 3 channels)

index 400 is out of bounds for axis 1 with size 368

im trying to build a face recognition model using CNN i have an image dataset that consists of 368 classes each class contains 15 images . im trying to use keras.utils.to_categorical on the image labels(class names which are numbers from 1-368 ) to set a specific label to 1 while set the others to zero during training.here is what i have done so far
import cv2
import numpy as np
import os
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from pathlib import Path
from sklearn.model_selection import train_test_split
SEED = 44000
data = []
label = []
BASE_FOLDER = r'C:\Users\Desktop\images\\'
folders = os.listdir(BASE_FOLDER)
for folder in folders:
for file in os.listdir(BASE_FOLDER + folder + '//'):
img = cv2.imread(BASE_FOLDER + folder + '//' + file)
data.append(img)
label.append(folder)
train_data, test_data, train_label, test_label = train_test_split(data, label, test_size=0.1, random_state=SEED)
train_data = np.array(train_data, dtype=np.float32)
test_data = np.array(test_data, dtype=np.float32)
train_data = train_data / 180 # to make the array values between 0-1. image size is 180 X 180
test_data = test_data / 180
train_label = list(map(int, train_label))
train_label = keras.utils.to_categorical(train_label, 368)
but i am getting this error
IndexError Traceback (most recent call last)
<ipython-input-69-f087078ef22a> in <module>
----> 1 train_label = keras.utils.to_categorical(train_label, 368)
~\Miniconda3\envs\tf_gpu\lib\site-packages\keras\utils\np_utils.py in to_categorical(y, num_classes, dtype)
32 n = y.shape[0]
33 categorical = np.zeros((n, num_classes), dtype=dtype)
---> 34 categorical[np.arange(n), y] = 1
35 output_shape = input_shape + (num_classes,)
36 categorical = np.reshape(categorical, output_shape)
IndexError: index 400 is out of bounds for axis 1 with size 368
whats the meaning of this error and how to solve it ?

Resources