Deep Learning Dataset Design for a Image Reference to Different Classes? - image

I want to training a image classifier using inception model.
Now, I have a dishes called chicken rice.
Suppose i want to create rice and chicken meat class.
So can i design output ground true probability as [0.5,0.5,0,0,0...]?
In other words, If the target image contains two classes' content, what should I do to make it reasonable?
Do somebody has tried this?
I have tried to train the image separately, and google did this, too.
keycnt = 0
imagcnt = 0
TestNumber_byclass = np.zeros([keycount],np.int32)
for key in TestKeys:
TestNumber_byclass[keycnt] = len(json_data_test[key])
for imagedata in json_data_test[key]:
imgdata = tf_resize_images(imagdir + imagedata + '.jpg')
imgdata = np.array(imgdata, dtype = np.uint8)
# make image center at 0 in the range of (-1,1]
#imgdata = (imgdata - mean - 128) / 128
h5f = h5py.File(h5filedir_test + str(imagcnt) + ".h5", "w")
h5f.create_dataset('image', data=imgdata)
h5f.create_dataset('label', data=keycnt)
h5f.create_dataset('name' , data=key)
h5f.close()
imagcnt = imagcnt + 1
keycnt =keycnt +1
message = '\r[%d/%d] progress...' % (keycnt,keycount)
sys.stdout.write(message)
sys.stdout.flush()
Many thanks.

What you're trying to do is a multiclass classification, where M out of N classes will be predicted. This is usually done by setting the flag to 1 if the object appears in the image and setting it to 0 if that's not the case.
The really important piece of information is that the last activation function needs to be a sigmoid instead of a softmax. That way you decouple the confidence for each class from the other classes and the sum will be between 0 and N.

Related

Remove small objects in a mask and generate a new binary mask out of for loop

I appreciate your help;
This part of the code allows me to plot what I want but I need to assign the outcome(a binary image with >500 area objects) to a variable for further processing
Improved_label = np.zeros_like(label_image)
#props = regionprops(label_image)
for R in regionprops(label_image):
if R.area > 500:
# draw the region (I'm sure there's a more efficient way of doing it)
for c in R.coords:
Improved_label[c[0], c[1]] = 1
#Improved_labe1 = Improved_label > 1
Apparently, there is something wrong with the name "improved" at the beginning of the variable name(not sure why). but anyhow, here are two solutions for this issue. I hope this will be helpful for people with the background in Matlab:
-------------Option A--------------
label2_test = np.zeros_like(label_image)
for R in regionprops(label_image):
if R.area > 1000:
# draw the region (I'm sure there's a more efficient way of doing it)
for c in R.coords:
label2_test[c[0], c[1]] = 1
label2_test = label2_test > 0
plt.imshow(labe2_test)
----------------Option B-----------------
from skimage import morphology
labe1_improved = morphology.remove_small_objects(label_image, min_size=1000)

How to save 3d arrays in Matlab that are generated in a loop?

I'm reading in 3d arrays, subtracting all of them from one of them, and trying to save the results as the same type of arrays. They are all equal sizes to each other, 1888x3520x6.
Here is the piece of code that I have:
[FileName,PathName,FilterIndex] = uigetfile('*.x3d*','MultiSelect','on');
numfiles = size(FileName,2);
FileName{1}
entirefile1 =fullfile(PathName,FileName{1})
Im1 = x3dread(entirefile1);
for j = 2:numfiles
FileName{j}
entirefile2 =fullfile(PathName,FileName{j})
Im2 = x3dread(entirefile2);
J = num2str(j);
strcat('ImDelta', J);
ImDelta = imsubtract(Im1, Im2);
end
I see that I'm creating a character sring by using strcat. But I'm not making it into a new file name. Only one file is resulting at the end of the loop.
(x3dread function is similar to "load" for working with images, only it is specifically written to handle the type of the 3dimention files that I have.)
Any help is appreciated. I'm just a beginner.

Reverse image search implementation

I am currently trying to make a site which will contain several images with patterns and shapes (Lets say few squares and circles of various colors and shape in each picture). And I am aiming to provide the user a way to upload their images of the pattern and do a reverse image search to check whether similar pattern image already exists in my site or not. So is there any way to implement the same, either by custom code or by using any third party api/widgets etc?
Hi Ashish below is a matlab code for a function which generates signature of a particular binary object's surface, which is nearly size dependent, you can use this concept for matching a shape on different scale.
function sig = signature(bw,prec)
boundry = bwboundaries(bw);
xy = boundry{1};
x = xy(:,1);
y = xy(:,2);
len = length(x);
res = (len/prec);
re = rem(res,2);
if re
res = ceil(res);
end
indexes = 1:res:len;
xnew = x(indexes);
ynew = y(indexes);
cx = round(mean(xnew));
cy = round(mean(ynew));
xn = abs(xnew-cx);
yn = abs(ynew-cy);
sig = (xn.^2+yn.^2);
sig = sig/max(sig);
Following is the example of how to use signature function:
clc
clear all
close all
path = 'E:\GoogleDrive\Mathworks\irisDEt\shapes';
im1 = imread([path,'\3.png']);
gray1 = ((im1));
scales = [1,2,3,4];
gray1 = im2bw(gray1);
for i = 1:length(scales)
im = imresize(gray1,scales(i));
sig = signature(im,25);
figure,plot(sig)
fra = getframe();
image = frame2im(fra);
imwrite(image,['E:\GoogleDrive\Mathworks\irisDEt\shapes\',num2str(i),'.png'])
end
following is the test image and its signature for changing in size od images which looks similar in shape.
All above signatures are generated by the code given above.

Issue with averaging images in matlab

when I try to average a folder of jpeg matlab images, all that I get is a blank image. I've gone over my code a million times, and I don't know where I'm
going wrong. (also I know I hard coded some of the numbers but that just because I wanted it to take a specific folder and I've double checked those a million times, they're right.)
%takes all the images in a folder and averages their values
%opens folder
function avg_image = average_images()
folder_name = uigetdir;
folder_directory = dir(folder_name);
filename = folder_directory(3).name;
len = length(folder_directory);
org_image = imread(filename);
sum_image = org_image;
%adds files together
for i = 4:len
filename = folder_directory(i).name;
org_image = imread(filename);
sum_image = sum_image + org_image;
end
%calculates average
avg_image = sum_image/(len-2);
%saves average as a fits file and displays it
imwrite(avg_image, 'averagefile.jpg');
read_image = imread('averagefile.jpg');
imshow(read_image)
end
The problem with your code is that you are reading in the JPGs as uint8 (default) and then doing math with the images as matrices of uint8's (0-255 integers). As you read in org_image, above and inside the for loop, cast the result as a double:org_image = double(imread(filename)). After you're done with the averaging, you need to cast it back, avg_image = uint8(sum_image/(len-2)).
When you do math with uint8's, divisions are messy since decimals are truncated. 4 divided by 8 when both are doubles gives you 0.5. When both are integers, you get 0.

RGB to norm rgb transformation. Vectorizing

I'm writing a piece of code that has to transform from an RGB image to an rgb normalized space. I've got it working with a for format but it runs too slow and I need to evaluate lots of images. I'm trying to vectorize the full function in order to faster it. What I have for the moment is the following:
R = im(:,:,1);
G = im(:,:,2);
B = im(:,:,3);
r=reshape(R,[],1);
g=reshape(G,[],1);
b=reshape(B,[],1);
clear R G B;
VNormalizedRed = r(:)/(r(:)+g(:)+b(:));
VNormalizedGreen = g(:)/(r(:)+g(:)+b(:));
VNormalizedBlue = b(:)/(r(:)+g(:)+b(:));
NormalizedRed = reshape(VNormalizedRed,height,width);
NormalizedGreen = reshape(VNormalizedGreen,height,width);
NormalizedBlue = reshape(VNormalizedBlue,height,width);
The main problem is that when it arrives at VNormalizedRed = r(:)/(r(:)+g(:)+b(:)); it displays an out of memory error (wich is really strange because i just have freed three vectors of the same size). Were is the error? (solved)
Its possible to do the same process in a more efficiently way?
Edit:
After using Martin sugestions I found the reshape function was not necessary, being able to do the same with a simple code:
R = im(:,:,1);
G = im(:,:,2);
B = im(:,:,3);
NormalizedRed = R(:,:)./sqrt(R(:,:).^2+G(:,:).^2+B(:,:).^2);
NormalizedGreen = G(:,:)./sqrt(R(:,:).^2+G(:,:).^2+B(:,:).^2);
NormalizedBlue = B(:,:)./sqrt(R(:,:).^2+G(:,:).^2+B(:,:).^2);
norm(:,:,1) = NormalizedRed(:,:);
norm(:,:,2) = NormalizedGreen(:,:);
norm(:,:,3) = NormalizedBlue(:,:);
I believe you want
VNormalizedRed = r(:)./(r(:)+g(:)+b(:));
Note the dot in front of the /, which specifies an element-by-element divide. Without the dot, you're solving a system of equations -- which is likely not what you want to do. This probably also explains why you're seeing the high memory consumption.
Your entire first code can be rewritten in one vectorized line:
im_normalized = bsxfun(#rdivide, im, sum(im,3,'native'));
Your second slightly modified version as:
im_normalized = bsxfun(#rdivide, im, sqrt(sum(im.^2,3,'native')));
BTW, you should be aware of the data type used for the image, otherwise one can get unexpected results (due to integer division for example). Therefore I would convert the image to double before performing the normalization calculations:
im = im2double(im);

Resources