When using the function regionprops in MATLAB, there is an option to extract the binary image of each connected component. The size of the binary image is reduced to the size of the connected component. I don't want the size of the binary image to reduce. I want the size of the binary image to retain its original size while only showing the selected connected component at its corresponding location in the original image size. How can I extract the connected component in the original image size?
Simply create a blank image that's the same size as your original image and instead of extracting the image per blob, extract the actual pixel locations with reference to the original image for each blob then populate the blank image by setting these locations to binary true in this blank image. Use the PixelIdxList attribute from regionprops to obtain the column major locations of your desired component, then use these to set the output image at these same locations to true.
Assuming your regionprops structure is stored in S and you want to extract out the kth component and the original image is stored in A, do the following:
% Allocate blank image
out = false(size(A, 1), size(A, 2));
% Run regionprops
S = regionprops(A, 'PixelIdxList');
% Determine which object to extract
k = ...; % Fill in ID here
% Obtain the indices
idx = S(k).PixelIdxList;
% Create the mask to be the same size as the original image
out(idx) = true;
imshow(out); % Show the final mask
If you have multiple objects and want to create this mask that is the original size of the image separately per object, you can use a for loop to do that for you:
% Run regionprops
S = regionprops(A, 'PixelIdxList');
% For each blob...
for k = 1 : numel(S)
out = false(size(A, 1), size(A, 2)); % Allocate blank image
% Extract out the kth object's indices
idx = S(k).PixelIdxList;
% Create the mask
out(idx) = true;
% Do your processing with out ...
% ...
end
Related
I'm trying to do some image analysis in Matlab. What I have is an image which I first convert into an binary image using a threshold and then I use bwlabel to get the BLOBs of the image. I then find the indexes of the first BLOB and tries to show only the RGB values of this BLOB I(row,column,:). However this obviously does not work and I don't know how to index the original image and get the corresponding RGB values based on the row, column data in the binary image. I suppose I could use a for-loop but the image is 4032 x 3024 and I want to do this kind of processing on a lot of images.
I = imread('someimg.jpg');
Ired = I(:,:,1);
Igreen = I(:,:,2);
Iblue = I(:,:,3);
% threshold
IBinary = Ired > 200 & Igreen > 150 & Iblue > 50;
IBinary = imopen(ISigns,strel('square',9));
% get labbelled BLOBs
IBinaryLabelled = bwlabel(IBinary,8);
% find index of the first label image
[row,column] = find(IBinaryLabelled == 1);
% Get RGB of the BLOB with label 1
RGB = I(row,column,:)
My question is therefore: How to get RGB values based on row,column data of binary image in an efficient manner?
I have the following code done whereby I import a frame from a film, convert to grayscale and draw by freehand the region of interest. I then use Chan-Vese region fill to get my region of interest and create a mask based on this. I can finally get the binary image I'm looking for which is called BW3 in the code. Now this is the silly part. How do I create a loop such that the code will run (load frames 1 to 58), present me with the grayscale image for frame 1, allow me to draw the region of interest and then create and save the final binary image BW3?
Regards,
J
% Select Initial Image
for n = 5:87
frame = read(obj,n);
%Isolate the Blade
imggray = rgb2gray(frame);
h_im=imshow(imggray);
%Region of interest
% r = imrect(gca,[646,188,18,-648]);
% BW2 = createMask(r,h_im);
hROI = imfreehand(gca);
Position = getPosition(hROI);
BW2 = createMask(hROI);
%Get blade Binary
BW3 = activecontour(imggray, BW2, 1000, 'Chan-Vese');
% Fill Holes
BW3 = imfill(BW3, 'holes');
% Form masked image from input image and segmented image.
maskedImage = h_im;
maskedImage(~BW3) = 0;
%Save binary frame
filename = sprintf('C:..........\\binaryimage%d.png', n);
imwrite(BW3,filename,'png');
end
Assuming that you have a limited number of frames (ie up to 58) you could just use a for loop to accomplish this. In your code, you will have to change the initial image code so that it iterates up with the loop.
for counter=1:58
frame=read(obj,counter);
imwrite(frame,strcat('frame',num2str(counter),'.png'))
.....% the remainder of your code likely remains unchanged.
end
When writing your results, you would likely need to drop it into a struct of some sort so that you can loop through unless you write your results to a file in each loop.
i have image that contain many blobs . my problem is that how to test each blob individually by masking it up on the original image?!
i tried this code but i did not know how to complete it
labelledImage = bwconncomp(segmentedimage);
stats = regionprops(labelledImage, 'all');
centroids = cat(1, stats.Centroid);
[row ,col] = size(centroids);
for i = 1 : row
areaMatr(i) = stats(i).Area; % gives area for each blob in your image
% what i have to put here for testing the blob and masking it out over the
% original image? any help?
end
It may be more prudent to use bwlabel instead, which assigns a unique ID to each unique blob in your image. The first output gives you this labelling and the second output gives you the total number of unique IDs / blobs in the image. Bear in mind that this image needs to be binary, but given your choice of variable name, I'm assuming this to be true.
Once you find all unique IDs, you can loop through each unique ID, mask out the blob and apply regionprops to this blob.
Something like this:
%// Apply bwlabel to the image
[labelledImage, numLabels] = bwlabel(segmentedimage);
%// For each label...
for idx = 1 : numLabels
%// Create a mask for this particular blob
mask = labelledImage == idx;
%// Apply regionprops on this mask only
stats = regionprops(mask, 'all');
%// Use stats and mask in however way you see fit
%// ...
%// ...
end
'stats.BoundingBox' will give you the coordinates of each blob. You can use the coordinates to mask the blob onto the original image.
After extracting HOG features of folder of images, I want to add all this results in one matrix. How I can do this? this is my code in matlab:
training_female = 'E:\Training Set\Female Images';
% read all images with specified extention, its jpg in our case
filenames = dir(fullfile(training_female, '*.jpg'));
% count total number of photos present in that folder
total_images = numel(filenames);
for n = 1:total_images
% Specify images names with full path and extension
full_name= fullfile(training_female, filenames(n).name);
% Read images
training_images = imread(full_name);
[featureVector, hogVisualization] = extractHOGFeatures(training_images);
figure (n)
% Show all images
imshow(training_images); hold on;
plot(hogVisualization);
end
By looking at the documentation, calling extractHOGFeatures computes a 1 x N vector given an input image. Because it can be a bit cumbersome to calculate what the output size of this may be, which also depends on what parameters you set up for the HOG detector, it's best to first create an empty matrix and dynamically concatenate the features at each iteration. Usually for performance you pre-allocate a matrix if you want to populate the elements on an iterative basis. Not doing it this way gives a slight ding in performance, but it's the most adaptable given your situation. You may want to adjust the HOG parameters and if we do it the dynamic way, that removes the headache of determining what the total size of the matrix should be.
So do something like this. I've placed %//New tags where I've modified your code:
training_female = 'E:\Training Set\Female Images';
% read all images with specified extention, its jpg in our case
filenames = dir(fullfile(training_female, '*.jpg'));
% count total number of photos present in that folder
total_images = numel(filenames);
featureMatrix = []; %// New - Declare feature matrix
for n = 1:total_images
% Specify images names with full path and extension
full_name= fullfile(training_female, filenames(n).name);
% Read images
training_images = imread(full_name);
[featureVector, hogVisualization] = extractHOGFeatures(training_images);
%// New - Add feature vector to matrix
featureMatrix = [featureMatrix; featureVector];
figure(n);
% Show all images
imshow(training_images); hold on;
plot(hogVisualization);
end
featureMatrix will contain your HOG features where each row is for each image. Therefore, for a particular image i, you can determine the HOG features by:
feature = featureMatrix(i,:);
Caveat
I need to mention that the above code assumes that all images in your directory are the same size. If they're not, then the output vector size for each HOG call is going to be different. If that's the case, you'll want to have a cell array to adapt for the different sizes.
Therefore, do something like this:
training_female = 'E:\Training Set\Female Images';
% read all images with specified extention, its jpg in our case
filenames = dir(fullfile(training_female, '*.jpg'));
% count total number of photos present in that folder
total_images = numel(filenames);
featureMatrix = cell(1,total_images); %// New - Declare feature matrix
for n = 1:total_images
% Specify images names with full path and extension
full_name= fullfile(training_female, filenames(n).name);
% Read images
training_images = imread(full_name);
[featureVector, hogVisualization] = extractHOGFeatures(training_images);
%// New - Add feature vector to matrix
featureMatrix{n} = featureVector;
figure(n);
% Show all images
imshow(training_images); hold on;
plot(hogVisualization);
end
To access a particular image's features, or image i, do:
feature = featureMatrix{i};
%clear workspace
clear;
clc;
close all;
%read Reference image and convert into single
rgb1= im2single(imread('r1.jpg'));
I1 = rgb2gray(rgb1);
%create mosaic background
sz= size(I1)+300;% Size of the mosaic
h=sz(1);
w=sz(2);
%create a world coordinate system
outputView = imref2d([h,w]);
%affine matrix
xtform = eye(3);
% Warp the current image onto the mosaic image
%using 2D affine geometric transformation
mosaic = imwarp(rgb1, affine2d(xtform),'OutputView', outputView);
figure,imshow(mosaic,'initialmagnification','fit');
%read Target image and convert into single
rgb2= im2single(imread('t1.jpg'));
I2 = rgb2gray(rgb2);
%find surf features of reference and target image ,then find new
%affine matrix
%Detect SURFFeatures in the reference image
points = detectSURFFeatures(I1);
%detectSURFFeatures returns information about SURF features detected
%in the 2-D grayscale input image . The detectSURFFeatures function
%implements the Speeded-Up Robust Features (SURF) algorithm
%to find blob features
%Extract feature vectors, also known as descriptors, and their
%corresponding locations
[featuresPrev, pointsPrev] = extractFeatures(I1,points);
%Detect SURFFeatures in the target image
points = detectSURFFeatures(I2);
%Extract feature vectors and their corresponding locations
[features, points] = extractFeatures(I2,points);
% Match features computed from the refernce and the target images
indexPairs = matchFeatures(features, featuresPrev);
% Find corresponding locations in the refernce and the target images
matchedPoints = points(indexPairs(:, 1), :);
matchedPointsPrev = pointsPrev(indexPairs(:, 2), :);
%compute a geometric transformation from the corresponding locations
tform=estimateGeometricTransform(matchedPoints,matchedPointsPrev,'affine');
%get affine matrix
xtform = tform.T;
% Warp the current image onto the mosaic image
mosaicnew = imwarp(rgb2, affine2d(xtform), 'OutputView', outputView);
figure,imshow(mosaicnew,'initialmagnification','fit');
%create a object to overlay one image over another
halphablender = vision.AlphaBlender('Operation', 'Binary mask', 'MaskSource', 'Input port');
% Creat a mask which specifies the region of the target image.
% BY Applying geometric transformation to image
mask= imwarp(ones(size(I2)), affine2d(xtform), 'OutputView', outputView)>=1;
figure,imshow(mask,'initialmagnification','fit');
%overlays one image over another
mosaicfinal = step(halphablender, mosaic,mosaicnew, mask);
% %show results
figure,imshow(rgb1,'initialmagnification','fit');
figure,imshow(rgb2,'initialmagnification','fit');
figure,imshow(mosaicfinal,'initialmagnification','fit');
There was an error when using the function 'imref2d' and this is the error that appeared.
Undefined function 'imref2d' for input arguments of type 'double'. Error in immosaic (line 13) outputView = imref2d([h,w]);
This manual will help you. You are using incorrect input in imref2d.