Outlines around segmented cells - matlab

The following lines, creates white rings (outlines) around my segmented cells
se1 = strel('diamond',10); se2 = strel('diamond',4);
R = imdilate([RED],se1)&[~imdilate([RED],se2)];
imshow(R)
And this line displays my segmented cells in RGB form.
r = imadjust(mat2gray(RED));
z = zeros(size(r),'like',r);
r = cat(3,r,z,z);
imshow(r)
Now, with a "hold on;" between two code, the outlines should be plotted around the red cells but it doesn't. I'm trying to plot white outlines around my segmented cells. Thanks for your help.

Related

Transparent overlapping bar plots

I want to have two transparent bar plots that overlape in one figure. I tried this way:
bar(list2(:,1),list2(:,2),'r','FaceAlpha',0.5)
hold on
bar(list1(:,1),list1(:,2),'g','FaceAlpha',0.5)
but the output is:
Why the second plot is not transparent and has these strange strips?
I use matlab 2016a
your approach is correct, and it works for a few bars:
[list1(:,2),list1(:,1)] = hist(randn(200,1));
[list2(:,2),list2(:,1)] = hist([randn(100,1)-0.5 ; randn(100,1)+0.5]);
bar(list2(:,1),list2(:,2),'r','FaceAlpha',0.5)
hold on
bar(list1(:,1),list1(:,2),'g','FaceAlpha',0.5)
However, you can notice that there are black lines contouring each bar. As the bar number increases, the black contours will cover everything:
[list1(:,2),list1(:,1)] = hist(randn(3000,1), 300);
[list2(:,2),list2(:,1)] = hist([randn(1500,1)-2 ; randn(1500,1)+2], 300);
h1 = bar(list2(:,1),list2(:,2),'r','FaceAlpha',0.5)
hold on
h2 = bar(list1(:,1),list1(:,2),'g','FaceAlpha',0.5)
(The result will depend on the Matlab version. In 2016b it appears that the problem is automatically corrected).
The solution: remove the black contours:
h1.EdgeColor = 'none';
h2.EdgeColor = 'none';

How to remove horizontal and vertical lines

I need to remove horizontal and vertical lines in a binary image. Is there any method for filtering these lines? bwareaopen() is not good method to remove these lines and also Dilation and Erosion are not good for these cases.
Does any one know a solution?
Example image:
EDIT:(added more example images:
http://s1.upload7.ir/downloads/pPqTDnmsmjHUGTEpbwnksf3uUkzncDwr/example%202.png
source file of images:
https://www.dropbox.com/sh/tamcdqk244ktoyp/AAAuxkmYgBkB8erNS9SajkGVa?dl=0
www.directexe.com/9cg/pics.rar
Use regionprops and remove regions with high eccentricity (meaning the region is long and thin) and orientation near 0 or near 90 degrees (regions which are vertical or horizontal).
Code:
img = im2double(rgb2gray(imread('removelines.jpg')));
mask = ~im2bw(img);
rp = regionprops(mask, 'PixelIdxList', 'Eccentricity', 'Orientation');
% Get high eccentricity and orientations at 90 and 0 degrees
rp = rp([rp.Eccentricity] > 0.95 & (abs([rp.Orientation]) < 2 | abs([rp.Orientation]) > 88));
mask(vertcat(rp.PixelIdxList)) = false;
imshow(mask);
Output:
If all of your images are the same where the horizontal and vertical lines are touching the border, a simple call to imclearborder will do the trick. imclearborder removes any object pixels that are touching the borders of the image. You'll need to invert the image so that the characters are white and the background is dark, then reinvert back, but I'm assuming that isn't an issue. However, to be sure that none of the actual characters get removed because they may also be touching the border, it may be prudent to artificially pad the top border of the image with a single pixel thickness, clear the border, then recrop.
im = imread('http://i.stack.imgur.com/L1hUa.jpg'); %// Read image directly from StackOverflow
im = ~im2bw(im); %// Convert to black and white and invert
im_pad = zeros(size(im,1)+1, size(im,2)) == 1; %// Pad the image too with a single pixel border
im_pad(2:end,:) = im;
out = ~imclearborder(im_pad); %// Clear border pixels then reinvert
out = out(2:end,:); %// Crop out padded pixels
imshow(out); %// Show image
We get this:
You can firstly find the horizontal and vertical lines. Since, the edge map will also be binary so you can perform a logical subtraction operation in between the images. To find vertical lines, you can use (in MATLAB)
BW = edge(I,'sobel','vertical');
For horizontal lines, you can use
% Generate horizontal edge emphasis kernel
h = fspecial('sobel');
% invert kernel to detect vertical edges
h = h';
J = imfilter(I,h);

After Using bwlabel in MATLAB,Can I change the labels of the connected components?

There are some white portions in a black object.
I need to cover up the all the white portions in the object with its neighboring black.
The bwlabel function labels the black part as '2' and white part as '1'.
can i somehow change the labels of the required object and cover the white portion with black.
I have isolated the objects individually using the following code:
a=imread('3.jpg');
figure(),imshow(a),title('Original image');
b=im2bw(a, graythresh(a));
figure(),imshow(b),title('Grayscale image');
[c,num]=bwlabel(b);
figure(),imshow(c),title('labelled image');
for i=1:1:num
figure(),imshow(c==i),title('OBJECT');
end
What can i do further ?
Or is there any other way to achieve the same?
Can you do
Find the indices of the white area
ind_white = find(c==1);
Replace the white area with zeros
b(ind_white) = 0;
or you can change the label of the white object to that of the black
c(ind) = 2;

Why sometimes the bars with bar or hist have no border?

I noticed that sometimes, when I plot the bars using the functions bar() or hist(), the bars plotted have no border. They are a little bit less nice to see, and I would prefer the border or a little bit of space between them.
The figure shows what I got now, plotting three different datasets. The third graph is zoomed in order to show the lack of space between bars.
I get there this has something to do with the 'histc' parameters in bar function. Without the histc parameters the bars have some space between each others, but then the bar will be centered on the edges values, whereas I want the edges values to be, well, EDGES of each bar.
This is (the relevant part of) the code I used:
[...]
if edges==0
%these following lines are used to take the min and max of the three dataset
maxx=max(cellfun(#max, reshape(data,1,size(data,1)*size(data,2))));
minn=min(cellfun(#min, reshape(data,1,size(data,1)*size(data,2))));
edges=minn:binW:maxx+binW;
end
[...]
y{k}=histc(data{r,c}, edges);
bar(edges,y{k} , 'histc');
[...]
I think if you change the color of your bar plots you'll see that there actually is a border it just doesn't show up very well. You can also change the width of the bars so that they are more distinct.
% something to plot
data = 100*rand(1000,1);
edges = 1:100;
hData = histc(data,edges);
figure
subplot(2,1,1)
h1 = bar(edges,hData,'histc');
% change colors
set(h1,'FaceColor','m')
set(h1,'EdgeColor','b')
% Change width
subplot(2,1,2)
h1 = bar(edges,hData,0.4,'histc');
The EdgeColor and LineWidth properties of the Barseries object control the bar outlines. Try using the code and playing with the red, green, blue, and width values to get a better result.
red = 1;
green = 1;
blue = 1;
width = 3;
h = bar(edges,y{k} , 'histc');
set(h,'EdgeColor',[red green blue],'LineWidth',width);

matlab: making an areaseries transparent disrupts subplots

I'm trying to make the red bands in the second subplot of the figure below go transparent with an opacity similar to alpha(0.2).
http://i.stack.imgur.com/zJjYk.jpg
However, when I try to call alpha(0.2) after the following code that generates the red bands:
Plotha1 = area([datenum(time(11,1),1,1) datenum(time(15,1),1,1)],[1.3*max(SA(:,2)) 1.3*max(SA(:,2))]);
set(Plotha1,'BaseValue',1.3*min(SA(:,2)),'FaceColor','r','LineStyle', 'none');
Plotha2 = area([datenum(time(4,1),1,1) datenum(time(8,1),1,1)],[1.3*max(SA(:,2)) 1.3*max(SA(:,2))]);
set(Plotha2,'BaseValue',1.3*min(SA(:,2)),'FaceColor','r','LineStyle', 'none');
alpha(0.2);
The third subplot goes blank like in the second figure.
http://i.stack.imgur.com/tjgIT.jpg
The code generating the third subplot comes last in my code:
subplot(3,1,3),
W = zeros(T,1);
PlotZeros = plot(datenum(time,1,1),W);
dateFormat = 'yyyy';
datetick('x',dateFormat);
hold on
PlotResid = plot(datenum(time,1,1),Resid);
set(PlotZeros,'Color',[0.5 0.5 0.5]); %grey
set(PlotResid,'Color','blue');
axis([datenum(time(1,1),1,1) datenum(time(end,1),1,1) 1.3*min(Resid) 1.3*max(Resid)])
hold off
I have tried moving things around so that the code generating the 2nd subplot comes last but it still causes the 3rd subplot to go blank. Does anyone know how to make these areaseries red bands go transparent without disrupting the 3rd subplot?
Thanks!
You could try using fill or patch with the 'facealpha' property instead of the area command:
% x and y vals define the 4 corners of the rectangle
% (slightly different than "area")
x_vals=[datenum(time(4,1),1,1) datenum(time(8,1),1,1) ...
datenum(time(8,1),1,1) datenum(time(4,1),1,1)];
y_vals=[1.3*min(SA(:,2)) 1.3*min(SA(:,2)) ...
1.3*max(SA(:,2)) 1.3*max(SA(:,2))];
Plotha2 = fill(x_vals,y_vals,'red','edgecolor','none','facealpha',0.2);