Suppose that I have an RGB image RGB and a binary image binary that contains the result of segmentation of image RGB. How to draw the image binary on top of image 'RGB` and show the segmentation as a red transparent area? I tried the following but I got an error. Please help me to figure out the best way in MATLAB
I=imread('RGB.png');
[M,N,C] = size(I);
h=imshow(I);
alpha= imread('binary.png');
alpha = cat(3,alpha,zeros(M,N), zeros(M,N));
set(h, 'AlphaData', alpha);
Here are the input images:
Here is a method to add red overlays in select regions of the mask. Modifications to these scripts can be made to fill in the remaining regions with the colours white or black. The regions of interest on the mask are selected using a logical array.
Overlay Red Over White Region of Mask
Overlay_Opacity = 0.5;
Image =imread('RGB.png');
imshow(Image);
Red_Channel = imread('binary.png');
White_Mask_Region = Overlay_Opacity*(Red_Channel ~= 0);
Overlay_Image(:,:,1) = White_Mask_Region;
Overlay_Image(:,:,2) = 0;
Overlay_Image(:,:,3) = 0;
hold on
Overlay = image(Overlay_Image);
Overlay.AlphaData = White_Mask_Region;
saveas(gcf,'Overlay_1.png');
Overlay Red Over Black Region of Mask
Overlay_Opacity = 0.5;
Image =imread('RGB.png');
imshow(Image);
Red_Channel = imread('binary.png');
Black_Mask_Region = Overlay_Opacity*(Red_Channel == 0);
Overlay_Image(:,:,1) = Black_Mask_Region;
Overlay_Image(:,:,2) = 0;
Overlay_Image(:,:,3) = 0;
hold on
Overlay = image(Overlay_Image);
Overlay.AlphaData = Black_Mask_Region;
saveas(gcf,'Overlay_2.png');
You simply use your binary alpha (one layer only) as AlphaData.
If you have the Image Processing Toolbox, this function will do what you want:
https://www.mathworks.com/help/images/ref/labeloverlay.html
Related
In Matlab/Octave (Image package) is it possible to draw a slightly transparent coloured rectangle over an image region?
For example; I want to draw a red rectangle (alpha/opacity of 0.5) over the top left corner of an image.
pkg load image;
pkg load signal;
i = imread('foo.jpg');
% Somehow draw a transparent rectangle over the top left of the image
imshow(i);
You can use hold on and the property 'AlphaData' to draw a transparent overlay as follows:
image = rand(100); % a random image
imshow(image); % show the image
% create the red overlay
red = zeros(100, 100, 3);
red(:, :, 1) = 1;
% create the alpha channel with the right transparency
alpha = zeros(100); % everywhere completely transparent
alpha(1:50, 1:50) = 0.5; % except for the top left corner
hold on
h = imshow(red); % show the overlay
set(h, 'AlphaData', alpha); % apply the transparency
I am new to MATLAB Image Processing and currently I have two images - one is a grayscale image of my object and the second is the scaled image generated from MATLAB using imagesc function. I am trying to overlay this scaled image on top of my grayscale image to get a spatial resolution for easier observation. Attached are the two images:
A) Grayscale Image:
B) Scaled Image:
There were a few difficulties that I encountered. Firstly, the scaled image is not saved in the same pixel dimensions, but I can get around that using the imwrite function:
im = imagesc(ScaledDiff);
imwrite(get(im,'cdata'),'scaleddiff.tif')
However, doing so will result in a loss of colorbar and the colormap. Secondly, even if I manage to shrink the scaled image to the size of the grayscale image, overlaying it is still a challenge. Ideally, I would like to set the transparency (or 'alpha') to 0 for those pixels with < 0.02 in scaled image value.
Any idea on how to do this will be greatly appreciated! Sorry if I was unclear!
UPDATE:
Thanks to Rotem, I have managed to overlay the grayscale image and a particular region of my heatmap:
However, I need to display the colorbar corresponding to the heatmap values, because otherwise the information is lost and the overlay will be useless. How should I do this? Below is a snippet of my code, where ScaledIntDiff contains the values from 0 to 0.25 that is displayed on the heatmap:
Brightfield = imread('gray.jpg'); % read background image
I1 = ind2rgb(gray2ind(Brightfield), gray); % convert indices into RGB scale
scale = 1000;
ScaledIntDiff2 = round(ScaledIntDiff.*scale);
I2 = ind2rgb(ScaledIntDiff2, jet(256)); % this is for the heatmap
threshold = 0.02;
I2R = I2(:,:,1); I2G = I2(:,:,2); I2B = I2(:,:,3);
I1R = I1(:,:,1); I1G = I1(:,:,2); I1B = I1(:,:,3);
% Replace pixels in I2 with pixels in I1 if the value of ScaledIntDiff of those pixels is below the threshold
I2R(ScaledIntDiff<threshold) = I1R([ScaledIntDiff<threshold]);
I2G(ScaledIntDiff<threshold) = I1G([ScaledIntDiff<threshold]);
I2B(ScaledIntDiff<threshold) = I1B([ScaledIntDiff<threshold]);
I2(:,:,1) = I2R; I2(:,:,2) = I2G; I2(:,:,3) = I2B;
figure
imshow(I2)
I know that the code above is highly inefficient, so suggestions on how to improve it will be very welcomed. Thank you!
Check the following:
I = imread('CKbi2Ll.jpg'); %Load input.
%Convert I to true color RGB image (all pixels R=G=B are gray color).
I1 = ind2rgb(I, gray(256));
%Convert I to true color RGB image with color map parula (instead of using imagesc)
I2 = ind2rgb(I, parula(256));
%Set the transparency (or 'alpha') to 0 for those pixels with < 0.02 in scaled image value.
%Instead of setting transparency, replace pixels with values from I1.
threshold = 0.02; %Set threshold to 0.02
I2(I1 < threshold) = I1(I1 < threshold);
%Blend I1 and I2 into J.
alpha = 0.3; %Take 0.3 from I2 and 0.7 from I1.
J = I2*alpha + I1*(1-alpha);
%Display output
imshow(J);
Adding a colorbar with ticks labels from 0 to 0.25:
Set color map to parula - it doesn't affect the displayed image, because image format is true color RGB.
Crate array of add 6 ticks from 0 to 250.
Create cell array of 6 TickLabels from 0 to 0.25.
Add colorbar with Ticks and TickLabels properties created earlier.
Add the following code after imshow(J);:
colormap(parula(256));
TLabels = cellstr(num2str((linspace(0, 0.25, 6))'));
T = linspace(1, 250, 6);
colorbar('Ticks', T', 'TickLabels', TLabels);
imshow('ClmypzU.jpg');
colormap(jet(256));
TLabels = cellstr(num2str((linspace(0, 0.25, 6))'));
T = linspace(1, 250, 6);
colorbar('Ticks', T', 'TickLabels', TLabels);
Greetings to all of you.
I have this somewhat frustrating problem, and I hope that you kindly help me solve it.
I am developing a human tracking system in MATLAB, and would like to show the result in an appealing GUI (also in MATLAB using GUIDE).
There is this main window where an image sequence of about 2500 gray scale images of size 320x240 would be played like a video but where the humans be outlined in them nicely.
The challenge is; these images need a bit of processing (detection outlining of humans) before being shown on the window.
Now, is it possible to display a set of images while at the same time do some processing for another set to be shown afterwards?
I would very much prefer it to play like a normal video, but I guess that would be somehow ambitious.
Here is an example showing a scenario similar to what you described. This was adapted from the demo I mentioned in the comments.
function ImgSeqDemo()
figure()
for i=1:10
%# read image
img = imread( sprintf('AT3_1m4_%02d.tif',i) );
%# process image to extract some object of interest
[BW,rect] = detectLargestCell(img);
%# show image
imshow(img), hold on
%# overlay mask in red color showing object
RGB = cat(3, BW.*255, zeros(size(BW),'uint8'), zeros(size(BW),'uint8'));
hImg = imshow(RGB); set(hImg, 'AlphaData',0.5);
%# show bounding rectangle
rectangle('Position', rect, 'EdgeColor','g');
hold off
drawnow
end
end
Here is the processing function used above. In your case, you would insert your algorithm instead:
function [BW,rect] = detectLargestCell(I)
%# OUTPUT
%# BW binary mask of largest detected cell
%# rect bounding box of largest detected cell
%# find components
[~, threshold] = edge(I, 'sobel');
BW = edge(I,'sobel', threshold*0.5);
se90 = strel('line', 3, 90);
se0 = strel('line', 3, 0);
BW = imdilate(BW, [se90 se0]);
BW = imclearborder(BW, 4);
BW = bwareaopen(BW, 200);
BW = bwmorph(BW, 'close');
BW = imfill(BW, 'holes');
%# keep largest component
CC = bwconncomp(BW);
stats = regionprops(CC, {'Area','BoundingBox'});
[~,idx] = max([stats.Area]);
rect = stats(idx).BoundingBox;
BW(:) = 0;
BW(CC.PixelIdxList{idx}) = 1;
end
I'm drawing an image using rgb pixel data. I need to set transparent background color for that image. What value I can set for alpha to be a transparent image? Or is there any other solution for this?
If I understand what you need, you basically want to turn specific colors on an image transparent. To do that you need to use getImageData check out mdn for an explanation on pixel manipulation.
Heres some sample code
var imgd = ctx.getImageData(0, 0, imageWidth, imageHeight),
pix = imgd.data;
for (var i = 0, n = pix.length; i <n; i += 4) {
var r = pix[i],
g = pix[i+1],
b = pix[i+2];
if(g > 150){
// If the green component value is higher than 150
// make the pixel transparent because i+3 is the alpha component
// values 0-255 work, 255 is solid
pix[i + 3] = 0;
}
}
ctx.putImageData(imgd, 0, 0);
And a working demo
With the above code you could check for fuschia by using
if(r == 255 && g == 0 && b == 255)
I think you want the clearRect canvas method:
http://www.w3schools.com/html5/canvas_clearrect.asp
This will let you clear pixels to transparent (or any other RGBA color) without fuss or pixel manipulation.
an alpha of 0 indications that pixel is completely transparent an alpha value of 255 is completely opaque meaning that it will have no transparency.
if you portions of your image are completely transparent (an alpha of 0) it doesn't matter what you use for the RGB values as long as use an Alpha of 0. On a side note some older windows programs that I have used make an assumption like the upper left pixel or the lower right pixel is to be used as the transparency color. It would then loop through all of the pixels and set the alpha to 0 when it encountered this specific RGB value.
If you use an Alpha of 127 and the image appeared on top of another image it would look like the two images are equally visible or that the bottom image is bleeding 50% of it's colors through to the top image.
Set a variable for alpha if you want to test and see what it looks like when you apply it to the entire image.
I have a 3D matrix im which represents an RGB image. I can do
imshow(im)
to display the image.
I want to display only one of the RGB channels at a time: I want to display the red channel and I want it to appear red.
I've tried
imshow(im(:,:,1))
but it displays the grayscale image (which is not what I want).
How do I display the red channel and make it appear red?
I have three proposals for you.
1.
Use the imagesc function and choose a red color palette.
2.
Clear the other color channels: im(:,:,2:3) = 0; imshow(im);
3. Use the ind2rgb function with a color map you build accordingly.
Try this:
% display one channel only
clear all;
im=imread('images/DSC1228L_512.jpg');
im_red = im;
im_green = im;
im_blue = im;
% Red channel only
im_red(:,:,2) = 0;
im_red(:,:,3) = 0;
figure, imshow(im_red);
% Green channel only
im_green(:,:,1) = 0;
im_green(:,:,3) = 0;
figure, imshow(im_green);
% Blue channel only
im_blue(:,:,1) = 0;
im_blue(:,:,2) = 0;
figure, imshow(im_blue);
Try this
I = imread('exemple.jpg');
%Red component
R = I(:,:,1);
image(R), colormap([[0:1/255:1]', zeros(256,1), zeros(256,1)]), colorbar;
%Green Component
G = I(:,:,2);
figure;
image(G), colormap([zeros(256,1),[0:1/255:1]', zeros(256,1)]), colorbar;
%Blue component
B = I(:,:,3);
figure;
image(B), colormap([zeros(256,1), zeros(256,1), [0:1/255:1]']), colorbar;
You mean you want to extract red color only?
using im(:,:,1) only seperate the red channel from the 3D image and convert it to a 2D image.
Try this simple code:
im=imread('example.jpg');
im_red=im(:,:,1);
im_gray=rgb2gray(im);
im_diff=imsubtract(im_red,im_gray);
imshow(im_diff);
For a better view, you could calculate and display the pure color. The formula Rp = Rc / (Rc + Gc + Bc). And a code example for the color red:
imagesc(im(:,:,1) ./ (im(:,:,1) + im(:,:,2) + im(:,:,3)))
This will make the color display more clearly, since the other colors have been filtered out.
I will try to illustrate it with an example:
Original image:
Red channel of image (im(:,:,1)):
Pure red: