Cropping layer in my keras model has zero dimensions - neural-network

I create simple model with keras to understand the cropping layer
def other_model():
x = keras.Input(shape = (64,64,3))
conv = keras.layers.Conv2D(5, 2)(x)
crop = keras.layers.Cropping2D(cropping = 32)(conv)
model = keras.Model(x,crop)
model.summary()
return model
But I get the following summary
Layer (type) Output Shape Param #
input_12 (InputLayer) (None, 64, 64, 3) 0
conv2d_21 (Conv2D) (None, 63, 63, 5) 65
cropping2d_13 (Cropping2D) (None, 0, 0, 5) 0
Total params: 65
Trainable params: 65
Non-trainable params: 0
Why are the 1st and the 2nd dimensions of Cropping2D equal to zero?
They are supposed to be 32

You can just choose the number of pixels which will be cut off at every side of your image. I would chose it bigger or equal than the half size of the image, so it didn't work

It is a bit unclear in the documentation, but if you give a single integer value (cropping=32) as parameter, it crops off 32 pixels on each side of the image.
If you have an image with 64x64 pixels and cropping=32, the target size therefore will be 0x0 pixels...
If you want to have a target size of 32x32 pixels, you have to give cropping=16

Related

Dividing the Image into user defined number of patches

I used to divide the image into equal number of patches. But now I have different state. I have image of different sizes such as 500x500, 125x125, 63x63, and 32x32.
I have to extract patch size of 20x20 pixels. How can I make a way to give the number of patches like 625, 144, 36, 9, and 4 patches to extract from image. It can be overlapped.
This is how I use to divide the image into equal sizes.
img_crop=slice1;
img_=imresize(img_crop,[1000,1000]);
[m,n,o] = size(img_);
nblockcolumn = 8;
nblockrow =8;
dcol = fix(n/nblockcolumn);
drow = fix(m/nblockrow);
indices = reshape(1:nblockrow* nblockcolumn,nblockcolumn,nblockrow);
for index = 1:nblockrow* nblockcolumn
[r,c] = ind2sub([nblockrow,nblockcolumn],index );
subimage{temp,:} = img_((r-1)*drow+1:r*drow, (c-1)*dcol+1:c*dcol,:);
temp=temp+1;
end

Why VGG-16 takes input size 512 * 7 * 7?

According to https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py
I don`t understand why VGG models take 512 * 7 * 7 input_size of fully-connected layer.
Last convolution layer is
nn.Conv2d(512, 512, kernel_size=3, padding=1),
nn.ReLU(True),
nn.MaxPool2d(kernel_size=2, stride=2, dilation=1)
Codes in above link.
class VGG(nn.Module):
def __init__(self, features, num_classes=1000, init_weights=True):
super(VGG, self).__init__()
self.features = features
self.classifier = nn.Sequential(
nn.Linear(512 * 7 * 7, 4096),
nn.ReLU(True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(True),
nn.Dropout(),
nn.Linear(4096, num_classes),
)
To understand this you have to know how the convolution operator works for CNNs.
nn.Conv2d(512, 512, kernel_size=3, padding=1) means that the input image to that convolution has 512 channels and that the output after the convolution is gonna be also 512 channels. The input image is going to be convolved with a kernel of size 3x3 that moves as a sliding window. Finally, the padding=1 means that before applying the convolution, we symmetrically add zeroes to the edges of the input matrix.
In the example you are saying, you can think that 512 is the depth while 7x7 is the width and height that is obtained by applying several convolutions. Imagine that we have an image with some width and height and we feed it to a convolution, the resulting size will be
owidth = floor(((width + 2*padW - kW) / dW) + 1)
oheight = floor(((height + 2*padH - kH) / dH) + 1)
where height and width are the original sizes, padW and padH are height and width (horizontal and vertical) padding, kW and kH are the kernel sizes and dW and dH are the width and height (horizontal and vertical) pixels that the kernel moves (i.e. if it is dW=1 first the kernel will be at pixel (0,0) and then move to (1,0) )
Usually the first convolution operator in a CNN looks like: nn.Conv2d(3, D, kernel_size=3, padding=1) because the original image has 3 input channels (RGB). Assuming that the input image has a size of 256x256x3 pixels if we apply the operator as defined before, the resulting image has the same width and height as the input image but its depth is now D. Simarly if we define the convolution as c = nn.Conv2d(3, 15, kernel_size=25, padding=0, stride=5) with kernel_size=25, no padding in the input image and with stride=5 (dW=dH=5, which means that the kernel moves 5 pixels each time if we are at (0,0) then it moves to (5,0), until we reach the end of the image on the x-axis then it moves to (0,5) -> (5,5) -> (5,15) until it reaches the end again) the resulting output image will have a size of 47x47xD
The VGG neural net has two sections of layers: the "feature" layer and the "classifier" layer. The input to the feature layer is always an image of size 224 x 224 pixels.
The feature layer has 5 nn.MaxPool2d(kernel_size=2, stride=2) convolutions. See referenced source code line 76: each 'M' character in the configurations sets up one MaxPool2d convolution.
A MaxPool2d convolution with these specific parameters reduces the tensor size in half. So we have 224 --> 112 --> 56 --> 28 --> 14 --> 7 which means that the output of the feature layer is a 512 channels * 7 * 7 tensor. This is the input to the "classifier" layer.

extract colored region

I want to extract each colored region in MATLAB after applying SRM segmentation method on a particular image.
I tried the following, but it seems that it extracts regions with different color (not the same color degree only), and with the largest area.
I = imread('./img/bfly.jpg');
imshow(I)
bw = im2bw(I);
imshow(bw)
L = bwlabel(bw);
imshow(L == 0)
props = regionprops(L);
[~,ind] = max([props.Area]);
imshow(L == ind);
Is there a way to extract each color separately?
This is an example image. I want to extract the brown color alone, the green color alone, and so on ...
Since your image appears to have no smooth variations of color, it should be straightforward to separate the colors into different images with unique to convert the image to label matrix (you could do this with rgb2ind also) followed by accumarray:
[Iu,ia,iu] = unique(reshape(I,[],3),'rows');
counts = accumarray(iu,1);
[counts,sortinds] = sort(counts,'descend');
Now say you want the N largest components:
N = 10;
largestLabels = sortinds(1:N);
Then the image for color ii:
mapi = reshape(iu == largestLabels(ii),size(I,1),size(I,2));
numeli = counts(ii)
The corresponding RGB values and the number of pixels of each color:
>> colorRegionSummary = [uint32(Iu(largestLabels,:)) counts(1:N)]
colorRegionSummary =
89 120 23 8206 % green
73 59 42 4370 % dark brown (wing)
64 128 184 2723 % blue (right shade)
105 136 25 2143 % green (bottom right shade)
64 127 178 1667 % blue (top left shade)
170 151 191 1380 % purple
58 132 201 1372 % blue (left shade)
177 130 45 1242 % orange (bottom wing shade)
184 123 50 1193 % orange (top wing shade)
118 114 56 586 % tan (top right)
Note that these are not connected components, just components with the same color. For a given mapi, you can then apply bwlabel to get the connected components for that color.
You could start with encoding the three color arrays (RGB) in a way so that you can merge them into one, two-dimensional array, e.g.
2Dimage = I(:,:,1) + 1e3*I(:,:,2) + 1e6*I(:,:,3)
that way, you get a unique number for each color: R + 1e3*G + 1e6*B. Note that each channel is encoded with a number in the interval [0, 255].
Now you can go and extract the different color regions from the image using
C = unique(2Dimage)
to obtain the unique colors you need to look for and then
for idx = 1:length(C)
find(C(idx)==2Dimage)
end
to locate the different parts of the image. The color can be readily obtained from the original image I at the corresponding locations/indices.

How to crop rows and columns of pixels out in MATLAB

I have an image with a white border around it, and I need to get rid of the border. There are 20 rows of white pixels above the image, 5 columns of white to the left, 5 of white columns to the right, and 5 rows of white below the image. I wan't to crop the image exactly out of that border, how do I do this in matlab? Thanks for any help you can give!
(The image is a tiff, which is why I can't use an online service for this, they won't let me upload .tiff)
What you need is the built-in MATLAB function imcrop. To use it, specify something like
B = imcrop(A,[xmin ymin width height]);
if A is your original image. First find the dimensions of your image. Say its 800 by 600. Then you are looking to crop a 770 by 580 image so these numbers respectively will be your width and height in the above function. Your x and y would be something like 5 and 20, respectively.
U can use imcrop for this if you have image processing toolbox or you can make new image as follows:
I2 = I(21:end-5, 6:end-5)
For 3 dimensions, you can use:
I2 = I(21:end-5,6:end-5,:)
For example as per your comment:
I = rand(153,1510,3);
size(I); % 153 1510 3
I2 = I(21:end-5,6:end-5,:);
size(I2); % 128 1500 3
newIm = oldIm(20:length(oldIm(:,1))-5,5:length(oldIm(1,:))-5)

Image/Color Comparison in Objective-C

I'm trying to find a way to compare two images.
Let me give you an example so you can better understand: my App will randomize a color (she will randomize a value from 0 to 255 for the R, then for the G and then for the B and the result is a completely random RGB color).
Now the user will take a photo from the camera of the iPhone and the App will comprare the color with the image.
Example: The App select the RGB = 205,133,63 wich is brown: the user will take a picture of a brown detail of a desk. Now I need to compare the brown selected by the iPhone and the brown of the picture and display a result (for example: "the pictures is faithful to 88% compared to the given color").
I found this example in internet, but I can figure out how I can implement this in my App: http://www.youtube.com/watch?v=hWRPn7IsChI
Thanks!!
Marco
There are plenty of ways you can do this. If you want to keep it simple, you can average the colours for your entire image. For the sake of simplicity, let's say your image only has two pixels:
RGB0 = 255, 0, 0 (red)
RGB1 = 0, 0, 0 (black)
Average between the two will be
RGB_AVG = 128, 0, 0 (dark red)
Now you can calculate the difference between this average and the selected colour 205, 133, 63. This too you can do in many different ways. Here is one:
R = 205 - 128 = 80
G = 133 - 0 = 133
B = 63 - 0 = 63
Total = 80 + 133 + 63 = 276
Total score = (756 - 276) / 756 = 63.5%
This is just one way, you could collect all colours in a dictionary and count them if you need it to be super accurate. It all depends on what you want to achieve.
Btw: Reassure your numbers don't end up being higher if they are higher than your sample color. Use ABS or whatever method you want. The above is just an example.