Draw mask on image with transparency - image

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

Related

batch crop quad images with diffenrent sizes to a circle

I have lots of images of planets in differing sizes like
They are all positioned exactly in the middle of the square images but with different height.
Now I want to crop them and make the black border transparent. I tried with convert (ImageMagick 6.9.10-23) like this:
for i in planet_*.jpg; do
nr=$(echo ${i/planet_/}|sed s/.jpg//g|xargs)
convert $i -fuzz 1% -transparent black trans/planet_${nr}.png
done
But this leaves some artifacts like:
Is there a command to crop all images in a circle, so the planet is untouched? (It mustn't be imagemagick).
I could also imagine a solution where I would use a larger -fuzz value and then fill all transparent pixels in the inner planet circle with black.
Those are all planets, I want to convert: download zip
Here is one way using Python Opencv from the minEclosingCircle.
Input:
import cv2
import numpy as np
import skimage.exposure
# read image
img = cv2.imread('planet.jpg')
h, w, c = img.shape
# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# get contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
# get enclosing circle
center, radius = cv2.minEnclosingCircle(big_contour)
cx = int(round(center[0]))
cy = int(round(center[1]))
rr = int(round(radius))
# draw outline circle over input
circle = img.copy()
cv2.circle(circle, (cx,cy), rr, (0, 0, 255), 1)
# draw white filled circle on black background as mask
mask = np.full((h,w), 0, dtype=np.uint8)
cv2.circle(mask, (cx,cy), rr, 255, -1)
# antialias
blur = cv2.GaussianBlur(mask, (0,0), sigmaX=2, sigmaY=2, borderType = cv2.BORDER_DEFAULT)
mask = skimage.exposure.rescale_intensity(blur, in_range=(127,255), out_range=(0,255))
# put mask into alpha channel to make outside transparent
imgT = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
imgT[:,:,3] = mask
# crop the image
ulx = int(cx-rr+0.5)
uly = int(cy-rr+0.5)
brx = int(cx+rr+0.5)
bry = int(cy+rr+0.5)
print(ulx,brx,uly,bry)
crop = imgT[uly:bry+1, ulx:brx+1]
# write result to disk
cv2.imwrite("planet_thresh.jpg", thresh)
cv2.imwrite("planet_circle.jpg", circle)
cv2.imwrite("planet_mask.jpg", mask)
cv2.imwrite("planet_transparent.png", imgT)
cv2.imwrite("planet_crop.png", crop)
# display it
cv2.imshow("thresh", thresh)
cv2.imshow("circle", circle)
cv2.imshow("mask", mask)
cv2.waitKey(0)
Threshold image:
Circle on input:
Mask image:
Transparent image:
Cropped transparent image:
packages to install
sudo apt install python3-opencv python3-sklearn python3-skimage

Add overlay image on top of other image

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

Overlaying MATLAB Scaled Image to Grayscale Image for selected pixels

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);

HTML5 how to draw transparent pixel image in canvas

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.

How do I display the red channel of an image in Matlab?

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:

Resources