The MATLAB code below is used to plot a plane and show constrain lines on the same plane.
The constrained areas are as below:
Area below the cyan line
Area below green line
Area below blue line (sorry, not very visible)
Area above red line
enter image description here
What is the simplest way to shade off (grayed out or something similar) the constrained region? (as shown below)
enter image description here
clc
clear;
close all;
[X1,X2] = meshgrid(0:10:3000,0:10:6000);
TEST = (33*X1 + 3*X2);
surf(X1,X2,TEST);
hold on;
X2 = cell(4,1);
X2{1,1} = 2*X1;
X2{2,1} = 6000-2*X1;
X2{3,1} = 9*X1;
X2{4,1} = (X1*0)+1200;
colour = cell(4,1);
colour{1,1} = 'r';
colour{2,1} = 'g';
colour{3,1} = 'b';
colour{4,1} = 'c';
for i = 1:4
TEST = (33*X1 + 3*X2{i,1});
h=surf(X1,X2{i,1},TEST);
set(h,'edgecolor',colour{i,1});
set(h,'LineWidth',2)
xlim([0 4000]);
ylim([0 7000]);
zlim([0 130000]);
hold on;
end
Related
In Matlab the image axes are shown as rows and columns (matrix style) which flip/cause the Y axis to start from the upper left corner. In the script below, I divide an outline to equally distance points using interparc (File Exchange link).
I wish to convert/adjust the calculated Y coordinates of the selected points so they will start from the “graph point of origin” (0,0; lower left corner) but without flipping the image. Any idea how to do this coordinates conversion?
Code:
clc;
clear;
close all;
readNumPoints = 8
numPoints = readNumPoints+1
url='https://icons.iconarchive.com/icons/thesquid.ink/free-flat-sample/512/owl-icon.png';
I = imread(url);
I = rgb2gray(I);
imshow(I);
BW = imbinarize(I);
BW = imfill(BW,'holes');
hold on;
[B,L] = bwboundaries(BW,'noholes');
k=1;
stat = regionprops(I,'Centroid');
b = B{k};
c = stat(k).Centroid;
y = b(:,2);
x = b(:,1);
plot(y, x, 'r', 'linewidth', 2);
pt = interparc(numPoints,x,y,'spline');
py = pt(:,2);
px = pt(:,1);
sz = 150;
scatter(py,px,sz,'d')
str =1:(numPoints-1);
plot(py, px, 'g', 'linewidth', 2);
text(py(1:(numPoints-1))+10,px(1:(numPoints-1))+10,string(str), 'Color', 'b');
pointList = table(py,px)
pointList(end,:) = []
You will need to flip the display direction of y-axis (as #If_You_Say_So suggested in the comment).
set(gca,'YDir','normal')
Y-axis is now pointing upward, but the image is displayed upside down. So we flip the y-data of the image as well.
I=flipud(I);
The image is flipped twice and is thus upright.
The data should be flipped before you plot it or do any calculation based on it. The direction of y-axis can be flipped later when you show the image or plot the outline.
url='https://icons.iconarchive.com/icons/thesquid.ink/free-flat-sample/512/owl-icon.png';
I = imread(url);
I = rgb2gray(I);
% Flip the data before `imshow`
I=flipud(I);
imshow(I);
% Flip the y-axis display
set(gca,'YDir','normal')
pointList =
py px
______ ______
1 109
149.02 17.356
362.37 20.77
512 113.26
413.99 270.84
368.89 505.99
141.7 508
98.986 266.62
Given two coordinate points A and B and its gradient 'slopes'. Now, I want to draw a line (with linspace - function) on an image which worked for lines with a gradient ~1. The line stopped at the image boundary (due to xlims and ylims).
imshow(I)
xlims = xlim(gca);
ylims = ylim(gca);
Now the problem: I try to repeat for another line which is nearly vertical and it did not stop at the image boundary (see picture):
Any solutions how I can draw a line using a y=mx+c equation that stops at the image boundary independent from the gradient?
EDIT:
img = uint8(zeros(382, 382));
pointA = [181.4594, 129.7092];
pointB = [185.3411, 251.6005];
imshow(img)
hold on
plot(pointA(1), pointA(2), 'ro')
plot(pointB(1), pointB(2), 'bo')
hold off
% From y = mx + x
slope = 31.4015;
intercept = -5.5684e+03;
xlims = xlim(gca);
ylims = ylim(gca);
y = xlims*slope + intercept;
Xline = linspace(xlims(1), xlims(2), 382);
Xline_pole1 = linspace(xlims(1), pointA(1), 382/2);
Xline_pole2 = linspace(xlims(2), pointB(1), 382/2);
Yline = Xline*slope + intercept;
Yline_pole1 = Xline_pole1*slope + intercept;
Yline_pole2 = Xline_pole2*slope + intercept;
hold on
plot( Xline_pole1, Yline_pole1, 'Color', 'b', 'LineWidth', 3 );
hold off
% Check how many coordinates are within image frame
for zz=1:length(Xline_pole1)
hold on
plot(Xline_pole1(zz),Yline_pole1(zz), 'm+');
end
Easy workaround:
Just reset your limits after you plotted your lines
imshow(I)
xlims = xlim(gca);
ylims = ylim(gca);
% plot your lines
xlim(xlims)
ylim(ylims)
I have two maps (matrices), and want to use them to generate the corresponding bivariate map.
The below code illustrates the idea using 'scatter', but because my original matrices are quite large, I need a different solution than to draw each point individually.
red_blue_colormap = brewermap(20,'RdYlBu'); %using ColorBrewer colormaps 'brewermap'
white2red = newmap(10:-1:1,:); %color map going from white to red
white2blue = newmap(11:20,:); %color map going from white to blue
X = rand(13,8); Y = rand(13,8); %sample matrices
figure;
for i=1:size(X,1)
for j=1:size(X,2)
portion_red = white2red(ceil(X(i,j)*10),:); %value between 'white' and 'red' corresponding to value of X(i,j)
portion_blue = white2blue(ceil(Y(i,j)*10),:);
subplot(2,2,1); hold on; title('X');
scatter(i,j,100,portion_red ,'s','filled');
subplot(2,2,2); hold on; title('Y');
scatter(i,j,100,portion_blue ,'s','filled');
subplot(2,2,3); hold on; title('X vs. Y');
w1 = Y(i,j)/(X(i,j) + Y(i,j)); %relative weight of 'Y'
color1 = portion_red - ((portion_red - portion_blue ) * w1);
scatter(i,j,100,color1,'s','filled');
subplot(2,2,4); hold on; title('Color matrix');
portion_red = white2red(ceil(i/size(X,1)*10),:);
portion_blue = white2blue(ceil(j/size(X,2)*10),:);
w2 = (j/size(X,2))/(i/size(X,1) + j/size(X,2));
color2 = portion_red - ((portion_red - portion_blue ) * w2);
scatter(i,j,100,color2,'s','filled');
end
end
This generates the following figure: https://image.ibb.co/kotP7m/bivariate_map.png
I want to plot the bottom left figure in a more efficient way. Any ideas?
I am working on a paper and I need to find out the area of the region having color black from the image that I have attached.
Original image
I have done some processing by using threshold and complimenting the image.Processed image
Now I'm having a problem finding the area of the black colored region. Can someone please help? I'm new to MATLAB.
Here is my code :
img1=imread('C:/Users/Allan/Desktop/unnamed1.jpg');
imshow(img1)
img1=rgb2gray(img1);
imshow(img1)
img2=im2bw(img1,graythresh(img1));
imshow(img2)
img2=~img2;
imshow(img2)
B = bwboundaries(img2);
imshow(img2)
hold on
for k = 1:length(B)
boundary = B{k};
plot(boundary(:,2), boundary(:,1), 'g', 'LineWidth', 0.2)
end
use regionprops or bwarea:
% take the NOT image
bw = ~img2;
% find individual regions
cc = bwconncomp(bw);
% find area for each black region
props = regionprops(cc,{'Area','Centroid'});
regionArea = [props(:).Area];
% find area of total black region
totalArea = bwarea(bw);
% plotting
for ii = find(regionArea > 100)
c = props(ii).Centroid;
text(c(1),c(2),num2str(regionArea(ii)),'Color','b',...
'HorizontalAlignment','center','VerticalAlignment','middle',...
'FontWeight','bold');
end
I labeled an image using CC = bwconncomp(BW); and masking the label with maximum area using code
numPixels = cellfun(#numel,CC.PixelIdxList);
[biggest,idx] = max(numPixels);
BW(CC.PixelIdxList{idx}) = 0;
Now I want to put thin rectangular box around that maximum area instead of masking it. How it can be done?
Full Code:
f = imread('test.PNG');
subplot(2,2,1); imshow(f,[]); title('Original Image');
for i = 1:3
Image = medfilt2(Image,[3 3]);
end
[Image_Num, num] = bwlabel(Image,8);
subplot(2,2,3); imshow(Image); title('after median filtering'); %labeling algorithm
BW=im2bw(Image);
subplot(2,2,4); imshow(BW); title('binary image');
CC = bwconncomp(BW); %area based segmentation
numPixels = cellfun(#numel,CC.PixelIdxList);
[biggest,idx] = max(numPixels);
BW(CC.PixelIdxList{idx}) = 0;
figure;
imshow(BW); title('AFTER AREA BASED MASKING');
You can use bwlabel with regionprops and rectangle annotation:
lb = bwlabel( bw ); %// label each CC
st = regionprops( lb, 'Area', 'BoundingBox' ); %// get area and bounding box for each region
[mxa mxi] = max( [st.Area] ); %// find max area region
Now you can annotate
figure;
imshow( bw ); hold on;
rectangle('Position', st(mxi).BoundingBox, 'EdgeColor', 'r' );
On the 'coins.png' image this results with:
CC.PixelIdxList{idx} will give you the linear indices of the locations in the image of where your object is located.
What you can do is use ind2sub to convert the linear indices to row and column locations, then we can determine the top left and bottom right corner of these row and column indices. Once we do this, we can thus mark your image accordingly.
Therefore:
%// Determine row and column locations
[row,col] = ind2sub(size(BW), CC.PixelIdxList{idx});
%// Get top left and bottom right coordinates
topleft_row = min(row);
topleft_col = min(col);
bottomright_row = max(row);
bottomright_col = max(col);
%// Draw a white box around the object
%// Left vertical line
BW(topleft_row:bottomright_row, topleft_col) = true;
%// Right vertical line
BW(topleft_row:bottomright_row, bottomright_col) = true;
%// Top horizontal line
BW(topleft_row, topleft_col:bottomright_col) = true;
%// Bottom horizontal line
BW(bottomright_row, topleft_col:bottomright_col) = true;
Here's an example using coins.png that's built-in to MATLAB. I read in the image, threshold it and fill in the holes.
im = imread('coins.png');
BW = im2bw(im, graythresh(im));
BW = imfill(O, 'holes');
When I do that and run the above code to draw a rectangle around the largest object, this is what I get:
Where this code ties into your program, don't do any masking. Replace the masking code with the above... so:
f = imread('test.PNG');
subplot(2,2,1); imshow(f,[]); title('Original Image');
for i = 1:3
Image = medfilt2(Image,[3 3]);
end
[Image_Num, num] = bwlabel(Image,8);
subplot(2,2,3); imshow(Image); title('after median filtering'); %labeling algorithm
BW=im2bw(Image);
subplot(2,2,4); imshow(BW); title('binary image');
CC = bwconncomp(BW); %area based segmentation
numPixels = cellfun(#numel,CC.PixelIdxList);
[biggest,idx] = max(numPixels);
%-------- CHANGE HERE
%// Determine row and column locations
[row,col] = ind2sub(size(BW), CC.PixelIdxList{idx});
%// Get top left and bottom right coordinates
topleft_row = min(row);
topleft_col = min(col);
bottomright_row = max(row);
bottomright_col = max(col);
%// Draw a white box around the object
%// Left vertical line
BW(topleft_row:bottomright_row, topleft_col) = true;
%// Right vertical line
BW(topleft_row:bottomright_row, bottomright_col) = true;
%// Top horizontal line
BW(topleft_row, topleft_col:bottomright_col) = true;
%// Bottom horizontal line
BW(bottomright_row, topleft_col:bottomright_col) = true;