Get pixel values in RGB images using PixelList in MATLAB - matlab

I am trying to get pixel intensity values from regions of interest in RGB images.
I segmented the image and saved the regions of interest (ROI) using regionprops 'PixelList' in MATLAB, as shown below:
In this example I am using "onion.png" image built in MATLAB. (But in reality I have hundreds of images, and each of them have several ROIs hence why I'm saving the ROIs separately.)
%SEGMENTATION PROGRAM:
a=imread('C:\Program Files\MATLAB\MATLAB Production Server\R2015a\toolbox\images\imdata\onion.png');warning('off', 'Images:initSize:adjustingMag');
figure; imshow(a,[]);
nrows = size(a,1);ncols = size(a,2);
zr=ones(nrows,ncols); %matrix of ones
r=a(:,:,1);g=a(:,:,2);b=a(:,:,3); %get RGB values
rr=double(r);gg=double(g);bb=double(b);% convert to double to avoid uint8 sums
bgd=(rr+bb)./(2*gg); %calculation RGB ratio of background
zr1=bgd>1.15; %matrix containing background as 1 and ROI as 0
% remake binary image for holes command which requires white object to fill % (this step is not relevant for this example, but it is for my data)
zr2=zr1<0.5;
zr3=imfill(zr2, 'holes');
figure;imshow(zr3); pause;
roi=regionprops(zr3,'Centroid','PixelList','Area');
ar=[roi.Area];
% find sort order , largest first
[as, ia]=sort(ar(1,:),'descend');
for w=1:length(roi); xy(w,:)=roi(w).Centroid;end
% use sort index to put cenrtoid list in same order
xy1=xy(ia,:);
%and pixel id list
for w=1:length(roi)
roi2(w).PixelList=roi(ia(w)).PixelList;
end
%extract centriod positions as two colums
%SAVE PIXEL LIST FOR EACH ROI IN A SEPARATE FILE
for ww=1:w;
k=roi2(ww).PixelList;
save('onion_PL','k');
end
How do I use this pixel list to get the intensity values in the original image? More specifically, I need to get the ratio of pixels in Green channel over Red ("grr=rdivide(gg,rr);"), but only in the region of interest labeled with PixelList. Here's my code so far:
%PL is the PixelList output we got above.
a=imread('C:\Program Files\MATLAB\MATLAB Production Server\R2015a\toolbox\images\imdata\onion.png');warning('off', 'Images:initSize:adjustingMag');
PL=dir(['*PL.mat']); %load file PixelList files. "dir" is a variable with directory path containing the pixelist files. In this example, we saved "onion_PL.mat"
for m=1:length(PL);
load(PL(m).name);
ex=[]; %empty matrix to hold the extracted values
for mm=1:length(k);
%INSERT ANSWER HERE
end
This next bit is wrong because it's based on the entire image ("a"), but it contains the calculations that I would like to perform in the ROIs
figure; imshow(a,[]);
pause;
nrows = size(a,1);ncols = size(a,2);
zr=ones(nrows,ncols); %matrix of ones
r=a(:,:,1);g=a(:,:,2);b=a(:,:,3); %get RGB values
rr=double(r);gg=double(g);bb=double(b);% convert to double to avoid uint8 sums
grr=rdivide(gg,rr);
I am brand new to MATLAB, so my code is not the greatest... Any suggestions will be greatly appreciated. Thank you in advance!

The loop you are looking for seems simple:
grr = zeros(nrows, ncols); % Initialize grr with zeros.
for mm = 1:length(k)
x = k(mm, 1); % Get the X (column) coordinate.
y = k(mm, 2); % Get the Y (row) coordinate.
grr(y, x) = gg(y, x) / rr(y, x);
end
A more efficient solution is using sub2ind for converting the x,y coordinates to linear indices:
% Convert k to linear indices.
kInd = sub2ind([nrows, ncols], k(:,2), k(:,1));
% Update only the indices in the PixelList.
grr(kInd) = rdivide(gg(kInd), rr(kInd));
In your given code sample there are 5 PixelLists.
I don't know how do you want to "arrange" the result.
In my code sample, I am saving the 5 results to 5 mat files.
Here is an executable code sample:
close all
%SEGMENTATION PROGRAM:
a=imread('onion.png');warning('off', 'Images:initSize:adjustingMag');
figure; imshow(a,[]);
nrows = size(a,1);ncols = size(a,2);
zr=ones(nrows,ncols); %matrix of ones
r=a(:,:,1);g=a(:,:,2);b=a(:,:,3); %get RGB values
rr=double(r);gg=double(g);bb=double(b);% convert to double to avoid uint8 sums
bgd=(rr+bb)./(2*gg); %calculation RGB ratio of background
zr1=bgd>1.15; %matrix containing background as 1 and ROI as 0
% remake binary image for holes command which requires white object to fill % (this step is not relevant for this example, but it is for my data)
zr2=zr1<0.5;
zr3=imfill(zr2, 'holes');
figure;imshow(zr3); %pause;
roi=regionprops(zr3,'Centroid','PixelList','Area');
ar=[roi.Area];
% find sort order , largest first
[as, ia]=sort(ar(1,:),'descend');
for w=1:length(roi); xy(w,:)=roi(w).Centroid;end
% use sort index to put cenrtoid list in same order
xy1=xy(ia,:);
%and pixel id list
for w=1:length(roi)
roi2(w).PixelList=roi(ia(w)).PixelList;
end
%extract centroid positions as two columns
%SAVE PIXEL LIST FOR EACH ROI IN A SEPARATE FILE
for ww=1:w
k=roi2(ww).PixelList;
%save('onion_PL', 'k');
save(['onion', num2str(ww), '_PL'], 'k'); % Store in multiple files - onion1_PL.mat, onion2_PL.mat, ... onion5_PL.mat
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear % Use clear for testing - the variables are going to be read from the mat file.
%PL is the PixelList output we got above.
a=imread('onion.png');warning('off', 'Images:initSize:adjustingMag');
nrows = size(a,1);ncols = size(a,2);
zr=ones(nrows,ncols); %matrix of ones
r=a(:,:,1);g=a(:,:,2);b=a(:,:,3); %get RGB values
rr=double(r);gg=double(g);bb=double(b);% convert to double to avoid uint8 sums
grr=rdivide(gg,rr);
PL=dir('*PL.mat'); %load file PixelList files. "dir" is a variable with directory path containing the pixelist files. In this example, we saved "onion_PL.mat"
for m = 1:length(PL)
load(PL(m).name);
ex=[]; %empty matrix to hold the extracted values
%for mm=1:length(k)
%INSERT ANSWER HERE
grr = zeros(nrows, ncols); % Initialize grr with zeros.
for mm = 1:length(k)
x = k(mm, 1); % Get the X (column) coordinate.
y = k(mm, 2); % Get the Y (row) coordinate.
grr(y, x) = gg(y, x) / rr(y, x);
end
% Instead of using a loop, it's more efficient to use sub2ind
if false
% Convert k to linear indices.
kInd = sub2ind([nrows, ncols], k(:,2), k(:,1));
% Update only the indices in the PixelList.
grr(kInd) = rdivide(gg(kInd), rr(kInd));
end
figure;imshow(grr);title(['grr of m=', num2str(m)]) % Show grr for testing.
save(['grr', num2str(m)], 'grr'); % Save grr for testing.
imwrite(imadjust(grr, stretchlim(grr)), ['grr', num2str(m), '.png']); % Store grr as image for testing
end
First two grr matrices as images (used for testing):
grr1.png:
grr2.png:

Related

Matlab - Plotting Specific Pixels (image treatment)

I'm currently struggling with an image treatment\ data plotting issue and was hoping to get some feedback from people with more experience than myself on this matter.
I'll try and breakdown the problem as to make it more understandable:
I have an original image (figureB - which is the blue chanel of the original image) of size NxM, from this image I select a specific area to study (NewfigureB), size 120x170;
I then divide this area into what I called macropixels which are 10x10 arrays of data points (pixels);
I then apply a mask to the selected area to select only the points meeting certain luminescence conditions;
So far so good. My problem comes when I try to plot a histogram of each of these macropixels when applying the luminescence mask. The final objective is to then find the peaks in these histograms.
so far this is what I've come up with. Any help would be greatly appreciated.
Many thanks
%Make the number of pixels in the matrix divisible
Macropixel = 10; %determine the size of the macropixel
[rows,columns] = size(figureB); %determine dimentions of the matrix used in the calculations
MacropixRows = floor(rows/Macropixel); %determine how many macropixels are in a row of the original matrix
MacropixColumn = floor(columns/Macropixel); %determine how many macropixels are in a column of the original matrix
%define new dim for the matrix
rows = MacropixRows * Macropixel;
columns = MacropixColumn * Macropixel;
NewfigureB = figureB(1:rows,1:columns); %divisible by the size of the macropixels created
%select area
NewfigureB = NewfigureB(1230:1349,2100:2269);
%create luminescence mask
Lmin=50;
hmax=80;
mask=false(size(NewfigureB));
mask(NewfigureB <Lmin)=true;
mask=mask & (NewfigureB<hmax);
%Apply mask
NewfigureB=NewfigureB(mask);
for jj = 1:Macropixel:120
for ii =1:Macropixel:170
histogram( NewfigureB(jj:jj+Macropixel-1, ii:ii+Macropixel-1))
end
end'''
The code you have posted has too many issues.
I tried to correct it the best I could.
I modified some parameters to feat the sample image I used.
I couldn't find your sample image, so I used the following
Here is a corrected code (please read the comments):
I = imread('Nikon-D810-Image-Sample-7.jpg');
figureB = I(:,:,3);
%Make the number of pixels in the matrix divisible
Macropixel = 10; %determine the size of the macropixel
[rows,columns] = size(figureB); %determine dimentions of the matrix used in the calculations
MacropixRows = floor(rows/Macropixel); %determine how many macropixels are in a row of the original matrix
MacropixColumn = floor(columns/Macropixel); %determine how many macropixels are in a column of the original matrix
%define new dim for the matrix
rows = MacropixRows * Macropixel;
columns = MacropixColumn * Macropixel;
NewfigureB = figureB(1:rows,1:columns); %divisible by the size of the macropixels created
%select area
NewfigureB = NewfigureB(1230:1349,2100:2269);
%create luminescence mask
Lmin=90;%50; %Change to 90 for testing
hmax=200;%80; %Change to 200 for testing
mask=false(size(NewfigureB));
mask(NewfigureB > Lmin)=true; %I think it should be > Lmin. %mask(NewfigureB <Lmin)=true;
mask=mask & (NewfigureB<hmax);
%This is not the right way to apply a mask, because the result is a vector (not a matrix).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Apply mask
%NewfigureB=NewfigureB(mask);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Assuming there are no zeros in the image, you can set masked elements to zero:
NewfigureB(~mask) = 0;
for jj = 1:Macropixel:120
for ii =1:Macropixel:170
%Copy NewfigureB(jj:jj+Macropixel-1, ii:ii+Macropixel-1) into temporary matrix MB:
MB = NewfigureB(jj:jj+Macropixel-1, ii:ii+Macropixel-1);
%Remove the zeros from MB (zeros are masked elements).
%The result is a vector (not a matrix).
MB = MB(MB ~= 0);
%histogram( NewfigureB(jj:jj+Macropixel-1, ii:ii+Macropixel-1))
figure; %Open new figure for each histogram. (I don't know if it's a good idea).
histogram(MB); %Plot the histogram of vector MB.
end
end
It's probably not exactly matches intentions.
I hope it gives you a lead...

How to draw a line between two coordinates of an image permanently in Matlab? [duplicate]

This question already has answers here:
MATLAB: Drawing a line over a black and white image
(5 answers)
Closed 4 years ago.
I have a set of points that I want to connect sequentially. Suppose the points are (A1,A2,A3,...A9); I want to connect A1 to A2, A2 to A3 and so on and finally connect A9 to A1.
All I need is to know a function that would help me connect A1 to A2, I could do the rest using for loops.
I know connecting two points is a question that has been asked here several times before but I couldn't find the answer I required. Several of the solutions suggest using "plot" and "line" but these functions overlay the results on the image and don't actually make any changes to the original image.
I did try them out and managed to save the resulting figure using the "saveas" and "print" functions but the image doesn't get saved in the proper format and there are a lot of problems using the parameters for these functions. Besides, I don't really want to save the image, it's just an unnecessary overhead I was willing to add if I could get the desired image with the lines.
I've also tried "imline" to draw lines but it seems to be interactive.
This particular question reflects my problem perfectly but when I ran the code snippets given as solutions, all of them gave a set of dots in the resulting image.
I tried the above mentioned codes in the link with this image that I found here.
A dotted line was an output for all three code snippets in the link above.
For example, I ran the first code like this:
I = imread('berries_copy.png');
grayImage=rgb2gray(I);
img =false(size(grayImage,1), size(grayImage,2));
I wrote the above piece of code just to get a black image for the following operations:
x = [500 470]; % x coordinates
y = [300 310]; % y coordinates
nPoints = max(abs(diff(x)), abs(diff(y)))+1; % Number of points in line
rIndex = round(linspace(y(1), y(2), nPoints)); % Row indices
cIndex = round(linspace(x(1), x(2), nPoints)); % Column indices
index = sub2ind(size(img), rIndex, cIndex); % Linear indices
img(index) = 255; % Set the line points to white
imshow(img); % Display the image
This is the resulting image for the above code as well as the other two, which as you can see, is just a few points on a black background which isn't the desired output.
I changed the code and used the "plot" function for the same to get this output which is what I want. Is there anyway I can change the dotted output into a solid line?
Or if could anyone suggest a simple function or a method that would draw a line from A1 to A2 and would actually make a change in the input image, I'd be grateful. (I really hope this is just me being a novice rather than Matlab not having a simple function to draw a line in an image.)
P.S. I don't have the Computer Vision toolbox and if possible, I'd like to find a solution that doesn't involve it.
Your first problem is that you are creating a blank image the same size as the image you load with this line:
img =false(size(grayImage,1), size(grayImage,2));
When you add the line to it, you get a black image with a white line on it, as expected.
Your second problem is that you are trying to apply a solution for grayscale intensity images to an RGB (Truecolor) image, which requires you to modify the data at the given indices for all three color planes (red, green, and blue). Here's how you can modify the grayscale solution from my other answer:
img = imread('berries_copy.png'); % Load image
[R, C, D] = size(img); % Get dimension sizes, D should be 3
x = [500 470]; % x coordinates
y = [300 310]; % y coordinates
nPoints = max(abs(diff(x)), abs(diff(y)))+1; % Number of points in line
rIndex = round(linspace(y(1), y(2), nPoints)); % Row indices
cIndex = round(linspace(x(1), x(2), nPoints)); % Column indices
index = sub2ind([R C], rIndex, cIndex); % Linear indices
img(index) = 255; % Modify red plane
img(index+R*C) = 255; % Modify green plane
img(index+2*R*C) = 255; % Modify blue plane
imshow(img); % Display image
imwrite(img, 'berries_line.png'); % Save image, if desired
And the resulting image (note the white line above the berry in the bottom right corner):
You can use the Bresenham Algorithm. Of course it has been implemented and you can find it here: Bresenham optimized for Matlab. This algorithm selects the pixels approximating a line.
A simple example, using your variable name could be:
I = rgb2gray(imread('peppers.png'));
A1 = [1 1];
A2 = [40 40];
[x y] = bresenham(A1(1),A1(2),A2(1),A2(2));
ind = sub2ind(size(I),x,y);
I(ind) = 255;
imshow(I)
You can use imshow to display a image and then use plot to plot lines and save the figure. Check the below code:
I = imread('peppers.png') ;
imshow(I)
hold on
[m,n,p] = size(I) ;
%% Get random points A1, A2,..A10
N = 9 ;
x = (n-1)*rand(1,N)+1 ;
y = (m-1)*rand(1,N)+1 ;
P = [x; y]; % coordinates / points
c = mean(P,2); % mean/ central point
d = P-c ; % vectors connecting the central point and the given points
th = atan2(d(2,:),d(1,:)); % angle above x axis
[th, idx] = sort(th); % sorting the angles
P = P(:,idx); % sorting the given points
P = [P P(:,1)]; % add the first at the end to close the polygon
plot( P(1,:), P(2,:), 'k');
saveas(gcf,'image.png')

creating a loop to save images from contour slice

I have the following code to plot a slice at any location in a fluid volume.
clc, clear all, close all
format long
%a ddpath('\\ds.leeds.ac.uk\staff\staff6\censsar\Polydisperse'); % <------Change
%% Import data
input = importdata('lci_000210.dat',' ',3);
nx = 96;
ny = 96;
nz = 49;
x = input.data(:,1);
y = input.data(:,2);
z = input.data(:,3);
Lci = input.data(:,4);
L3d = reshape(Lci,[nx,ny,nz]);
x3d = reshape(x,[nx,ny,nz]);
y3d = reshape(y,[nx,ny,nz]);
z3d = reshape(z,[nx,ny,nz]);
contourslice(y3d,x3d,z3d,L3d,[],[],[0.3]);
ax=gca;
ax.Children(1).LineStyle='none';
ax.Children(2).LineStyle='none';
ax.Children(3).LineStyle='none';
view(25,20);
colormap jet
colorbar
What I would like to do is have the contour slice in a loop so that it creates and saves a slice at each z location. I want to hopefully create a movie of the z slice moving from zero and going up the 3d axis.
I have tried something like:
Z=[0 0.1 0.5];
for S = 1:length(Z)
h = figure
contourslice(y3d,x3d,z3d,L3d,[],[],[Z],10);
saveas(h,sprintf('Fig%d.png',S));
end
but this is not working, I am not sure how to define the z axis in the loop, so it creates a slice at each point.
Here is the link to my data, it is a .dat file so it contains the data in 4 columns.
To create a set of slices in a loop you have to modify your code by replacing the last but one parameter in the call to contourslice by specifiybg the i-th element of the array Z.
Since you did not post your input data I've tested the proposed solution on an example data from MatLab contourslice help slightly modified in which
are created nine contour plots in the y-z plane, no plots in the x-z plane, and one plot in the x-y plane by specifying Sx as a vector of nine elements, Sy as an empty vector, and Sz as a scalar (from MatLab help).
Yoy have to adapt the definition of the Sx, Sy and Sz parameters to your needs.
To create a movie you can use the functions:
videowriter to create the video object
open to open the video file
getframe to capture axes or figure as movie frame
close to close and save the video file
As an alternative to the movie, you can create an animated gif by using the function imwrite
% Load input data
[X,Y,Z,V] = flow;
% Define the parameters for the set of slices
Sx = 1:9;
Sy = [];
Sz = [];
cvals = linspace(-8,2,10);
% Open the FIGURE window
figure
% Create the axes and set tehiur properties
axis([0,10,-3,3,-3,3])
hold on
daspect([1,1,1])
campos([0,-20,7])
box on
% Create the movie object
mov=VideoWriter('contour_slice_movie.avi');
% Open the movie file
open(mov);
% Define the number of frames to be captured for each slice
n_frame_x_image=33;
% Loop over the desired number of slices
for i=1:length(Sx)
contourslice(X,Y,Z,V,Sx(i),Sy,Sz,cvals)
% Capture the frames
for j=1:n_frame_x_image
FF=getframe(gcf);
writeVideo(mov,FF);
end
end
% Close the movie file
close(mov);

Colour Segmentation by l*a*b

I'm using the code on the MatLab website, "Color-Based Segmentation Using the Lab* Color Space":
http://www.mathworks.com/help/images/examples/color-based-segmentation-using-the-l-a-b-color-space.html
So I'm trying to select some areas myself instead of using the "load region_coordinates", using roipoly(fabric), but i get stuck. How do I save coordinates of the polygon I just drew? I'm actually following advice from lennon310 at Solution II, bottom of page:
A few questions about color segmentation with L*a*b*
I'm not sure when to save region_coordinates and do size(region_coordinates,1)
I made the following changes (Step 1):
1) Removed "load region_coordinates"
2) Added "region_coordinates = roipoly(fabric);"
Here's the code:
`
%% Step 1
fabric = imread(file);
figure(1); %Create figure window. "If h is not the handle and is not the Number property value of an existing figure, but is an integer, then figure(h) creates a figure object and assigns its Number property the value h."
imshow(fabric)
title('fabric')
%load regioncoordinates; % 6 marices(?) labelled val(:,:,1-6), 5x2 (row x column)
region_coordinates = roipoly(fabric);
nColors = 6;
sample_regions = false([size(fabric,1) size(fabric,2) nColors]); %Initializing an Image Dimension, 3x3 (:,:,:) to zero? Zeros() for arrays only I guess.
%Size one is column, size two is row?
for count = 1:nColors
sample_regions(:,:,count) = roipoly(fabric,region_coordinates(:,1,count),region_coordinates(:,2,count));
end
figure, imshow(sample_regions(:,:,2)),title('sample region for red');
%%Step 2
% Convert your fabric RGB image into an L*a*b* image using rgb2lab .
lab_fabric = rgb2lab(fabric);
%Calculate the mean a* and b* value for each area that you extracted with roipoly. These values serve as your color markers in a*b* space.
a = lab_fabric(:,:,2);
b = lab_fabric(:,:,3);
color_markers = zeros([nColors, 2]);%... I think this is initializing a 6x2 blank(0) array for colour storage. 6 for colours, 2 for a&b colourspace.
for count = 1:nColors
color_markers(count,1) = mean2(a(sample_regions(:,:,count))); %Label for repmat, Marker for
color_markers(count,2) = mean2(b(sample_regions(:,:,count)));
end
%For example, the average color of the red sample region in a*b* space is
fprintf('[%0.3f,%0.3f] \n',color_markers(2,1),color_markers(2,2));
%% Step 3: Classify Each Pixel Using the Nearest Neighbor Rule
%
color_labels = 0:nColors-1;
% Initialize matrices to be used in the nearest neighbor classification.
a = double(a);
b = double(b);
distance = zeros([size(a), nColors]);
%Perform classification, Elucidean Distance.
for count = 1:nColors
distance(:,:,count) = ( (a - color_markers(count,1)).^2 + (b - color_markers(count,2)).^2 ).^0.5;
end
[~, label] = min(distance,[],3);
label = color_labels(label);
clear distance;
%% Step 4: Display Results of Nearest Neighbor Classification
%
% The label matrix contains a color label for each pixel in the fabric image.
% Use the label matrix to separate objects in the original fabric image by color.
rgb_label = repmat(label,[1 1 3]);
segmented_images = zeros([size(fabric), nColors],'uint8');
for count = 1:nColors
color = fabric;
color(rgb_label ~= color_labels(count)) = 0;
segmented_images(:,:,:,count) = color;
end
%figure, imshow(segmented_images(:,:,:,1)), title('Background of Fabric');
%Looks different somehow.
figure, imshow(segmented_images(:,:,:,2)), title('red objects');
figure, imshow(segmented_images(:,:,:,3)), title('green objects');
figure, imshow(segmented_images(:,:,:,4)), title('purple objects');
figure, imshow(segmented_images(:,:,:,5)), title('magenta objects');
figure, imshow(segmented_images(:,:,:,6)), title('yellow objects');
`
You can retrieve the coordinates of the polygon using output arguments in the call to roipoly. You can then get a binary mask of the polygon, as well as vertices coordinates if you want.
Simple example demonstrating:
clear
clc
close all
A = imread('cameraman.tif');
figure;
imshow(A)
%// The vertices of the polygon are stored in xi and yi;
%// PolyMask is a binary image where pixels == 1 are white.
[polyMask, xi, yi] = roipoly(A);
This looks like this:
And if you wish to see the vertices with the binary mask:
%// display polymask
imshow(polyMask)
hold on
%// Highlight vertices in red
scatter(xi,yi,60,'r')
hold off
Which gives the following:
So to summarize:
1) The polygon's vertices are stored in xi and yi.
2) You can plot the binaryMask of the polygon using imshow(polyMask).
3) If you need the coordinates of the white pixels, you can use something like this:
[row_white,col_white] = find(polyMask == 1);
You're then good to go. Hope that helps!

How do I create an image matrix with a line drawn in it in MATLAB?

I want to plot a line from one well-defined point to another and then turn it into an image matrix to use a Gaussian filter on it for smoothing. For this I use the functions line and getframe to plot a line and capture the figure window in an image, but getframe is very slow and not very reliable. I noticed that it does not capture anything when the computer is locked and I got an out of memory error after 170 executions.
My questions are:
Is there a substitute to getframe that I can use?
Is there a way to create the image matrix and draw the line directly in it?
Here is a minimal code sample:
figure1=line([30 35] ,[200 60]);
F= getframe;
hsize=40; sigma=20;
h = fspecial('gaussian',hsize,sigma);
filteredImg = imfilter(double(F.cdata), h,256);
imshow(uint8(filteredImg));
[update]
High-Performance Mark's idea with linspace looks very promising, but how do I access the matrix coordinates calculated with linspace? I tried the following code, but it does not work as I think it should. I assume it is a very simple and basic MATLAB thing, but I just can not wrap my head around it:
matrix=zeros(200,60);
diagonal=round([linspace(30,200,numSteps); linspace(35,60,numSteps)]);
matrix(diagonal(1,:), diagonal(2,:))=1;
imshow(matrix);
Here's one example of drawing a line directly into a matrix. First, we'll create a matrix of zeros for an empty image:
mat = zeros(250, 250, 'uint8'); % A 250-by-250 matrix of type uint8
Then, let's say we want to draw a line running from (30, 35) to (200, 60). We'll first compute how many pixels long the line will have to be:
x = [30 200]; % x coordinates (running along matrix columns)
y = [35 60]; % y coordinates (running along matrix rows)
nPoints = max(abs(diff(x)), abs(diff(y)))+1; % Number of points in line
Next, we compute row and column indices for the line pixels using linspace, convert them from subscripted indices to linear indices using sub2ind, then use them to modify mat:
rIndex = round(linspace(y(1), y(2), nPoints)); % Row indices
cIndex = round(linspace(x(1), x(2), nPoints)); % Column indices
index = sub2ind(size(mat), rIndex, cIndex); % Linear indices
mat(index) = 255; % Set the line pixels to the max value of 255 for uint8 types
You can then visualize the line and the filtered version with the following:
subplot(1, 2, 1);
image(mat); % Show original line image
colormap(gray); % Change colormap
title('Line');
subplot(1, 2, 2);
h = fspecial('gaussian', 20, 10); % Create filter
filteredImg = imfilter(mat, h); % Filter image
image(filteredImg); % Show filtered line image
title('Filtered line');
If you have Computer Vision System toolbox there is a ShapeInserter object available. This can be used to draw lines, circles, rectangles and polygons on the image.
mat = zeros(250,250,'uint8');
shapeInserter = vision.ShapeInserter('Shape', 'Lines', 'BorderColor', 'White');
y = step(shapeInserter, mat, int32([30 60 180 210]));
imshow(y);
http://www.mathworks.com/help/vision/ref/vision.shapeinserterclass.html
You can check my answer here. It is robust way to achieve what you are asking for. Advantage of my approach is that it doesn't need additional parameters to control density of the line drawn.
Something like this:
[linspace(30,200,numSteps); linspace(35,60,numSteps)]
Does that work for you ?
Mark