Dividing the Image into user defined number of patches - matlab

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

Related

Why can't I colour my segmented region from the original image

I have the following code:
close all;
star = imread('/Users/name/Desktop/folder/pics/OnTheBeach.png');
blrtype = fspecial('average',[3 3]);
blurred = imfilter(star, blrtype);
[rows,cols,planes] = size(star);
R = star(:,:,1); G = star(:,:,2); B = star(:,:,3);
starS = zeros(rows,cols);
ind = find(R > 190 & R < 240 & G > 100 & G < 170 & B > 20 & B < 160);
starS(ind) = 1;
K = imfill(starS,'holes');
stats = regionprops(logical(K), 'Area', 'Solidity');
ind = ([stats.Area] > 250 & [stats.Solidity] > 0.1);
L = bwlabel(K);
result = ismember(L,find(ind));
Up to this point I load an image, blur to filter out some noise, do colour segmentation to find the specific objects which fall in that range, then create a binary image that has value 1 for the object's colour, and 0 for all other stuff. Finally I do region filtering to remove any clutter that was left in the image so I'm only left with the objects I'm looking for.
Now I want to recolour the original image based on the segmentation mask to change the colour of the starfish. I want to create Red,Green,Blue channels, assign value to them then lay the mask over the image. (To have red starfishes for example)
red = star;
red(starS) = starS(:,:,255);
green = star;
green(starS) = starS(:,:,0);
blue = star;
blue(starS) = star(:,:,0);
out = cat(3, red, green, blue);
imshow(out);
This gives me an error: Index exceeds matrix dimensions.
Error in Project4 (line 28)
red(starS) = starS(:,:,255);
What is wrong with my current approach?
Your code is kinda confusing... I don't understand whether the mask you want to use is starS or result since both look like 2d indexers. In your second code snippet you used starS, but the mask you posted in your question is result.
Anyway, no matter what your desired mask is, all you have to do is to use the imoverlay function. Here is a small example based on your code:
out = imoverlay(star,result,[1 0 0]);
imshow(out);
and here is the output:
If the opaque mask of imoverlay suggested by Tommaso is not what you're after, you can modify the RGB values of the input to cast a hue over the selected pixels without saturating them. It is only slightly more involved.
I = find(result);
gives you an index of the pixels in the 2D image. However, star is 3D. Those indices will point at the same pixels, but only at the first 2D slice. That is, if I points at pixel (x,y), it is equivalently pointing to pixel (x,y,1). That is the red component of the pixel. To index (x,y,2) and (x,y,2), the green and blue components, you need to increment I by numel(result) and 2*numel(result). That is, star(I) accesses the red component of the selected pixels, star(I+numel(result)) accesses the green component, and star(I+2*numel(result)) accesses the blue component.
Now that we can access these values, how do we modify their color?
This is what imoverlay does:
I = find(result);
out = star;
out(I) = 255; % red channel
I = I + numel(result);
out(I) = 0; % green channel
I = I + numel(result);
out(I) = 0; % blue channel
Instead, you can increase the brightness of the red proportionally, and decrease the green and blue. This will change the hue, increase saturation, and preserve the changes in intensity within the stars. I suggest the gamma function, because it will not cause strong saturation artefacts:
I = find(result);
out = double(star)/255;
out(I) = out(I).^0.5; % red channel
I = I + numel(result);
out(I) = out(I).^1.5; % green channel
I = I + numel(result);
out(I) = out(I).^1.5; % blue channel
imshow(out)
By increasing the 1.5 and decreasing the 0.5 you can make the effect stronger.

How to get pixel color from Matlab imaq.VideoDevice step() output

I'm using step() in imaq.VideoDevice, but can't find description of format of step() output. Am using thermal infrared camera, and want to filter for specific temperature range.
So, I want to use step() on each frame, and then search the frame for pixels within specific thermal range. And obviously need to know the X,Y of each pixel, too.
My goal is to filter pixels from a frame and leave only pixels within desired temperature.
You probably need to get the information on temperature and color from your IR camera. Look up the documentation it probably says which values correspond to what pixel values. At that point you just create a mask for each frame. something like this (Assuming the values from the ir camera is "grayscale', meanign there is only one channel)
highest_temp = 200; %just a random number
lowest_temp = 50;
my_mask = (im <= higest_Temp) & (im >= loest_temp);
my_mask is a logical array with a 0 when the pixel is outside the range, and a 1 (true) when the pixel is inside the range. IF you want to apply the mask to the image just multiply them together (and take care of units, here I assume the IR camera is <16 bits)
masked_im = uint16(im .* double(mask));
I would also use trigger function rather than step If I'm not mistaken the trigger action should take only 1 image/frame by default. so Make a loop, grab a frame, do your processing, then go to the next loop iteration, over and over. Hope that helps
Answer:
step() outputs ROW X COLUMN X pixel_color
where pixel_color = index 1 is the amount of red in the pixel.
pixel_color = index 2 is the amount of green in the pixel.
pixel_color = index 3 is the amount of blue in the pixel.
For example, for color of pixel at X, Y = 5,10 = row 5, column 10
then:
amount of red = (5, 10, 1)
amount of green is = (5, 10, 2)
amount of blue is = (5, 10, 3)
EXAMPLE USAGE THAT DISPLAY A FRAME WITH RED COLUMN AND GREEN ROW........
% Get a video frame:
load('handshakeStereoParams.mat');
videoFileLeft = 'handshake_left.avi';
readerLeft = vision.VideoFileReader(videoFileLeft, 'VideoOutputDataType', 'uint8');
frameLeft = readerLeft.step();
live_scene_player = vision.VideoPlayer('Position', [20, 600, 850, 500], 'Name','LEFT');
% Make green horizontal stripe at row 10 on the image:
frameLeft(10,:,1)=0; % remove red from stripe
frameLeft(10,:,2)=255; % turn on all green
frameLeft(10,:,3)=0; % remove blue from stripe
% Make red horizontal stripe at column 10 on the image:
frameLeft(:,10,1)=255; % remove red from stripe
frameLeft(:,10,2)=0; % turn on all green
frameLeft(:,10,3)=0; % remove blue from stripe
% display it:
step( live_scene_player, frameLeft); % originally from frameLeftRect

Make strip of nan in a matrice matlab

I have an image size (m x n x 4) I want to make strip of 0 or NaNon it. I want the strips to be 4 pixels wide and having a space of about 30 pixels between them. That is when I display the image in RGB I have strips of NaN. Can somebody help me out with this, please?
I interpreted you question as "how can I repeatedly draw black lines with a given width and a specified offset over an image".
img = imread('peppers.png');
height = size(img,1);
strip_width = 4;
strip_offset = 30;
line_start_idx = 0:(strip_width+strip_offset):height;
line_idx = ndgrid(line_start_idx,1:strip_width)';
line_idx = line_idx(:);
line_add = repmat(1:strip_width,1,length(line_start_idx))';
line_idx = line_idx + line_add;
img(line_idx,:,:) = 0;
imshow(img)

How to find maximum pixel intensity of the two regions obtained after finding the threshold of the image

We are working on DIP project where we found out the threshold of the gray scale image. Now we have to * find the maximum intensity of the two regions that we got, one region whose pixels are less than the threshold and the other whose pixels are greater than it. *
PS. We are not converting the image into binary image after finding the threshold. We just have to separate pixels in two regions and find the maximum intensity in each region
PS: We are working on MATLAB
Actually it is pretty simple to do.
Here is a function to do so:
function [ lowThrMaxIntns, highThrMaxIntns ] = FindMaxIntnesity ( mInputImage, thrLevel )
% Pixels which are lower than the threshold level
mLowThrImage = zeros(size(mInputImage));
% Pixels which are higher than the threshold level
mHightThrImage = zeros(size(mInputImage));
mLowThrImage(mInputImage < thrLevel) = mInputImage(mInputImage < thrLevel);
mHightThrImage(mInputImage >= thrLevel) = mInputImage(mInputImage >= thrLevel);
[lowThrMaxIntns lowThrMaxIntnsIdx] = max(mLowThrImage(:));
[highThrMaxIntns highThrMaxIntnsIdx] = max(mHightThrImage(:));
end
The output are only the intensities of the pixels.
If you need the pixel location, use the Idx variables (Use ind2sub for the sub scripts form).

Matlab fill shapes by white

As you see, I have shapes and their white boundaries. I want to fill the shapes in white color.
The input is:
I would like to get this output:
Can anybody help me please with this code? it doesn't change the black ellipses to white.
Thanks alot :]]
I = imread('untitled4.bmp');
Ibw = im2bw(I);
CC = bwconncomp(Ibw); %Ibw is my binary image
stats = regionprops(CC,'pixellist');
% pass all over the stats
for i=1:length(stats),
size = length(stats(i).PixelList);
% check only the relevant stats (the black ellipses)
if size >150 && size < 600
% fill the black pixel by white
x = round(mean(stats(i).PixelList(:,2)));
y = round(mean(stats(i).PixelList(:,1)));
Ibw = imfill(Ibw, [x, y]);
end;
end;
imshow(Ibw);
Your code can be improved and simplified as follows. First, negating Ibw and using BWCONNCOMP to find 4-connected components will give you indices for each black region. Second, sorting the connected regions by the number of pixels in them and choosing all but the largest two will give you indices for all the smaller circular regions. Finally, the linear indices of these smaller regions can be collected and used to fill in the regions with white. Here's the code (quite a bit shorter and not requiring any loops):
I = imread('untitled4.bmp');
Ibw = im2bw(I);
CC = bwconncomp(~Ibw, 4);
[~, sortIndex] = sort(cellfun('prodofsize', CC.PixelIdxList));
Ifilled = Ibw;
Ifilled(vertcat(CC.PixelIdxList{sortIndex(1:end-2)})) = true;
imshow(Ifilled);
And here's the resulting image:
If your images are all black&white, and you have the image processing toolkit, then this looks like what you need:
http://www.mathworks.co.uk/help/toolbox/images/ref/imfill.html
Something like:
imfill(image, [startX, startY])
where startX, startY is a pixel in the area that you want to fill.