Matlab: Gradient color spots according to percentage - matlab

I want to paint some edges on my plot using gradient color according to their repetition percentage.
So the most repeated edge on my graph to be red, the next lesser to be orange and the edge with the less repetitions to be light beige.
The Percentage of the repetition can be obtained from a txt file.
The rest area of the plot i would like to stay intact in white color. Something like the next image (consider objects shape and size irrelevant, just the color gradient is what i am interested for).
How can i do this with matlab?
My approach so far:
EDIT it works with the addition of the hold all cmd
for jkl=1:size(edges,1)
plot(edges(jkl,1), edges(jk,2),'^','Color',[edgespercentage(jkl)/100 0 1], 'LineWidth', 2.5,'DisplayName', 'Edges with gradient color'); hold all
end
But as i see plot cant keep each iteration's color and plots at the end the last calculated color only (as expected).
Thank you in advance.
Solution found with the tip of David K (Thank you!)

I'm not sure if this is exactly what you want, but give it a shot:
mesh(xvals,yvals,zvals,repititionVals);
colormap('hot');
You can play around with colormap to get the exact shading you want, but I think either hot or autumn is the closest predefined map to what you're looking for

Related

What's the most efficient way of identifying items of a specific shade of colour in an image with matlab?

im trying to identify a specific shade of green leaves (e.g. navy green) from the attached image. how do i do that in the most efficient way? So far, i'm converting the RGB to HSV and then thresholding the image based on some specific range of saturation and value that will isolate my desired shade. it's working on some images and it's just all over the place on others. i want something that can isolate a specific shade of green in any different image that has slightly different saturation and value (e.g. if the picture was taken with too much light)
Image link
pic=imread('image.jpg');
q=rgb2hsv(pic);
H=q(:,:,1);
S=q(:,:,2);
V=q(:,:,3);
thresh=S>0.6111 & S<0.6666 & V>0.3888 & V<0.4583;
st=strel('diamond',20);
w=imdilate(thresh,st);
comps=bwconncomp(w,8);
num=comps.NumObjects;
fprintf('The number of leaves is %i',num)
% then i try to have some pointers on the image to show me where matlab has identified the the shade.
m = regionprops(w,'centroid');
boxes = cat(1, m.Centroid);
imshow(pic)
hold on
plot(boxes(:,1),boxes(:,2), 'b*')
hold off
Your help will be highly appreciated.
Either the HSV color space (hey, S is saturation and V value), where H will give you the hue,or CIE-Lab color space, where euclidean distance will give you how close 2 specific pixel are to each other in color.
This answer explains how to do it for HSV: Segment pixels in an image based on colour (Matlab)
Using combined with CIE-LAB may help if the colors are very close together (like the greens in each leaf), but you should give HSV a shot

Border of a scatter plot in Matlab: constructing it and colouring it

I would like your help to plot the border of a scatter in Matlab and fill it with a specified colour.
Let me firstly show you how the scatter looks like.
scatter(x,y)
Now, let me show you what I have tried to design the border.
k = boundary(x,y);
plot(x(k),y(k));
which produces this
This is not what I want. Firstly, the scatter is nicely convex and I don't understand why boundary produces that weird shape. Secondly, I want to colour with blue inside the border.
Could you kindly advise on how to proceed? Also, when building the border I would prefer not to rely on the convexity of the scatter, because in some of my real examples the scatter is not convex.
Boundary
There is no easy way to get the boundary of a non-convex shape without any information on what is expected. When should the boundary follow the convex hull and when should deviate from it?
Matlab function boundary is generic, made to work with arbitrary input coordinates. It has a 'shrink factor' parameter s that can be tuned between 0 (convex hull) and 1 (highly non-convex), depending on the expected result.
% Make some x,y data with a missing corner
[x,y]=meshgrid(1:20);
sel=~(x>15 & y<=5);
x=x(sel);y=y(sel);
% Compute boundary with several values for s
k=boundary([x,y]); %Default shrink factor : 0.5
k_convhull=boundary([x,y],0);
k_closest=boundary([x,y],1);
% Plot the boundary:
plot(x,y,'ok') %black circles
hold on
plot(x(k),y(k),'-r') %red line
plot(x(k_convhull),y(k_convhull),'-g') %green line
plot(x(k_closest),y(k_closest),'-b') %blue line
The re-entrant corner is still somewhat cut, even with the 'shrink factor' set to 1. If this does not suit you, you will need to make your own function to compute the coordinates of the border.
Plot a surface
You need to use a patch object there.
p=patch(x(k3),y(k3),[1 .8 .8]);
uistack(p,'bottom')
[1 .8 .8] is the RGB color of the patch surface (light pink)
uistack is there to move the patch below the other graphic objects, because it is not transparent. It will still cover the axes grid, if any. Another option is :
p=patch(x(k3),y(k3),[1 0 0],'FaceAlpha',.2);
Here, the patch will be plain red and drawn on top of other objects, but has 80% transparency set through the alpha channel (0 is fully transparent, 1 is solid color).
Beware, the patch object class has so many options that is somewhat complex to handle beyond basic use cases like this one.

How to find edge from dark line to grey smeared region

I am trying to detect the edge from black horizontal line to the gray-smeared foreground.
The desired edge/result is slightly marked red.
What have I tried so far :
My approach was to use the standard Chan-Vese Segmentation combined with several preprocseeing methods like gaussian blurring, maximum filter or morpholigocal operator like erosion. However, when I am initializing the level set function at the lower part of the image, the contour gets stuck right before the dersired edge.
Due to the noise I can't get rid off without destroying important information of the image, simple methods like the sobel or prewitt filtering might fail.
Another apporoach of me was to search for the maximum/minimum intensity columnwise of the image and mark the darkest pixel per column.
As you can assume, this will fail too because the edge I am looking for is not the only part that has dark pixels, that's why this method is very error-prone.
Edit
Snakes does not help either.
The active contour, marked as blue, simply goes over the edge and at the left and right the contour gets stuck. The Code I tried wasthe function Snake2D(I,P,Options) taken from here.
Here is the original image if you would like to help me.
I think your approach using the rows and finding the maximum is probably easiest.
The one problem you have is distinguishing the two main maxima. For this, you can apply a rough smoothing, to find the middle between the two maxima (blue line in image below). You can then only take the lower bit, which is the one you are interested in and find the maximum of this bit.
In a final step, just add up the two indices.
Result:
Could go like this:
ib = imread('LHkm2.png'); %Read image
sz = size(ib); %get dimensions
for i = 1:sz(2)
[~, ind_mid(i)] = max(smooth(-double(ib(:, i)), 130));%First round
line_to_smooth = ib(ind_mid(i):end, i);%Get line with one maximum
[~, ind(i)] = min(smooth(double(line_to_smooth), 10));%Second round
ind(i) = ind(i) + ind_mid(i);%Add indices to get final position
end
imshow(ib,[]);
hold on;
plot(ind_mid, 'LineWidth', 3);
plot(ind, 'LineWidth', 3);
Note: You can of course smooth the final line just like any other graphs to get rid of bumps like this:
ind = smooth(ind, 10)
where 10 is your smoothing window (the higher the broader, see here.

Overlapping graphs in matlab

I am drawing several graphs in the same plot in matlab by using the command, hold on.
My problem is that I am drawing points with big markersize on top of some of the graphs, and I would like theses points to have some specific color. Only what happens is that some of them will take some color and some others take another color, my guess is that the colors of my points get mixed with the colors of the graphs on top of which i put them. Is there a mean to ask matlap to overwrite whatever is under my points so that they get the color I assign to them?
Example:
x= 0:1:10;
plot(x,x,'r',x,-x,'b','linewidth',2)
hold on
plot(5,-5,'.',10,10,'.','MarkerColor',[0,0.5,0],'Markersize',24)
hold on
plot(5,5,'.',10,-10,'.','MarkerFaceColor',[0,0.75,0],'MarkerSize', 24)
Imagine that the curves are much more complicated than theses simple lines so no way to start having fun cutting them each time I want to represent a point...
Now my problem is that I would like that the points 5,-5 and 10,10 to have the same color. Namely 0 0.5 0 dark green. but their color get mixed depending on which line they lie.
If I specify their color as '.g' I don't get this problem, but the problem is that I got too many points to get covered by the few number of colors that are labeled by letters (eg 'r' 'b' 'k' etc..).
Thankfully
Note that 'MarkerColor' doesn't exist, so I suppose it's a type and you meant 'MarkerFaceColor', just like in the other plot.
Then, hold on once is enough, you don't need to repeat it every time you want overlap another plot.
Finally, I suggest you simply use 'Color' instead of MarkerFaceColor. This should display your dots with the wanted color.
x= 0:1:10;
plot(x,x,'r',x,-x,'b','linewidth',2)
hold on
plot(5,-5,'.',10,10,'.','Color',[0,0.5,0],'Markersize',24)
plot(5,5,'.',10,-10,'.','Color',[0,0.75,0],'MarkerSize', 24)

How would you pixelate an image in Matlab without using the image toolbox?

mypicture=imread(filename); %inputs 1st image
[row col pan]=size(mypicture);
subplot(2,1,2)
pixpicture=mypicture;
image(pixpicture);
hold on;
for J=1:stepval:row
for K=1:stepval:col
pix=pixpicture(J,K,:);
x=[K K+stepval K K+stepval];
y=[J J J+stepval J+stepval];
plot(x,y);
hold all;
end
end
subplot (2,1,1)
image(mypicture);
end
I'm trying to pixelate an image without using the image processing toolbox. I was told the method, which is to take a pixel then color all of the surrounding pixels that color, however I'm having trouble doing this in my code. What I have above is what I've tried however it doesn't quite work as intended.
What are your suggestions?
Think of each pixel as three numbers, each corresponding to how much red, green and blue that pixel has. Say pixel=[128 35 0]
You then need to use those three values and assign them to the surrounding pixels.
pixpicture(J,K,:)=pix
Where the J and K values should correspond to all the neighbors of that pixel.
Give that a go, hopefully I said enough without just giving you the answer.
Having said all of that why don't you just reduce the size of the image using
pixelatedImage = imresize(mypicture, scale)
It would be much easier than trying to do that yourself. It doesn't look like you gave a thought to the cases where you have corners or how many pixels to change in the neighborhood...