How can I overlap two images/pictures in Matlab?
102 views (last 30 days)
Show older comments
I am trying to overlap two pictures one of them is in .jpg file and other is contour plot from MATlab. I want to overlap on one an other to compare the contour lines. Does any body know what code can be or any manual way?
0 Comments
Answers (3)
DGM
on 15 May 2022
Edited: DGM
on 24 Apr 2023
There's an awful lot of traffic on this question. I don't know that passers-by actually have the same intent, but let's assume some do.
The original question was about overlaying a contour map an an image. It almost reads as if both the contour map and the underlying image are (or are assumed to be) raster images. It's good advice to simply avoid such a scenario and plot the contour map on the image instead of recycling a rasterized copy that's likely been degraded due to any number of factors. There are a few points to consider in such an effort.
First of all, a contour plot uses the current axes colormap, but imshow()/image()/imagesc() also use the current colormap to display single-channel (grayscale) images. This causes problems if you want the two objects to use different colormaps. While you can work around it by creating duplicate axes, the simple solution is to just expand the image so that it doesn't require the use of the current colormap.
% some sort of image
%bgimage = imread('cameraman.tif'); % works for grayscale
bgimage = imread('jagblobs.png'); % or RGB images
% some sort of height information to make a contour map
heightdata = imgaussfilt(bgimage,20);
if size(bgimage,3) == 3
heightdata = rgb2gray(heightdata);
elseif size(bgimage,3) == 1
% need to expand single-channel images
% if you don't want them to share the same cmap as the contour
bgimage = repmat(bgimage,[1 1 3]);
end
% draw things
imshow(bgimage); hold on
contour(heightdata)
colormap(parula)
If you want to do the same with a contourf() plot, dealing with transparency is another issue to consider. See this answer for an example of a truncated semitransparent contourf() over an image. Take note of the chosen method and the link provided at the top for the opposite method.
That leaves the less-favorable prospect of trying to somehow overlay an image of a contour plot. I'm going to assume that the images have been registered/scaled/cropped somehow and ancillary plot features like labels, ticks, titles, and colorbars have been dealt with. I'm assuming you're not trying to do something like this:
I'm going to assume two simple images of identical geometry. Consider these two images:
Can you use imfuse() to combine them? You could. If you're using the image registration tools, it might offer a little bit of convenience in that it supports a workflow built around them.
% some sort of image
bgimage = imread('jagblobs.png');
% some sort of height information
fgimage = imread('jagblobcontours.png');
outpict = imfuse(fgimage,bgimage,'blend');
imshow(outpict)
So you could use imfuse(), but the results are pretty terrible. This should be expected, as imfuse() is a simple visualization tool for image comparison, not an image composition tool. The closest it can do is above, which is a simple opacity blend. Even if that's all you want, bear in mind that it can't even be adjusted. All imfuse() can do is a fixed 50% blend (i.e. it's just the arithmetic mean). If you want anything else, you'll won't be doing it with imfuse().
You can do simple adjustable opacity blending without imfuse(), though bear in mind that you'll have to pay attention to the numeric class, data range, and number of color channels when trying to do this.
% some sort of image
bgimage = imread('jagblobs.png');
% some sort of height information
fgimage = imread('jagblobcontours.png');
alph = 0.7; % at least it's adjustable
outpict = fgimage*alph + bgimage*(1-alph);
imshow(outpict)
Either way, the results of an opacity blend are generally going to look terrible. It might be about all you can do for a filled contour, but for an unfilled contour, it's obtrusive.
Instead of using imfuse(), how about making a binary mask and combining the images that way?
% some sort of image
bgimage = imread('jagblobs.png');
% some sort of height information
fgimage = imread('jagblobcontours.png');
% compose images
alph = ~all(fgimage>=254,3);
outpict = im2double(fgimage).*alph + im2double(bgimage).*(1-alph);
outpict = im2uint8(outpict);
% draw things
imshow(outpict)
I wouldn't exactly call that good. If visual appearances matter (especially with smooth images), using binary masking techniques is likely going to be an exercise in creating ragged, ugly results.
Unless the image itself is binarized or indexed, or unless the regions of interest are themselves defined by a clear logical boundary, a binary mask can only do one of two things. It can either underselect the region, or it can overselect. In this case, it's overselecting. Along with the colored lines, we're getting a significant amount of the near-white background adjacent to the lines. At native resolution, the colors are apparently very diluted by the white due to their contrast against the dark background image.
Since the contours are drawn on a white background, we can use the darkest color in each mask region and simply use that instead of the original foreground content.
% some sort of image
bgimage = imread('jagblobs.png');
% some sort of height information
fgimage = imread('jagblobcontours.png');
% get mask
alph = ~all(fgimage>=254,3);
% assuming contour bg is white
CC = bwconncomp(alph); % segment the mask
outpict = bgimage; % allocate output
for k = 1:CC.NumObjects
idx = CC.PixelIdxList{k} + [0 1 2]*numel(alph); % get indices in this ROI
regionpixels = reshape(fgimage(idx),[],3); % get pixels in this ROI
% replace bg content with darkest color in foreground region
outpict(idx) = repmat(min(regionpixels,[],1),[size(regionpixels,1) 1]);
end
% draw things
imshow(outpict)
The results are still jagged and ugly, but the colors are at least distinct. If we wanted to make the lines thinner, we could use bwskel() on the mask prior to segmentation.
Can we avoid binarization? Yes. There are a number of image blending methods that might work in certain cases depending on the content and intent, but for a plain contour map like this example, the following would be where I might start (if I had no other choice):
% some sort of image
bgimage = imread('jagblobs.png');
% some sort of height information
fgimage = imread('jagblobcontours.png');
% compose images
fgimage = color2alpha(fgimage,[1 1 1]); % make white transparent
fgimage(:,:,4) = imadjust(fgimage(:,:,4)); % boost opacity
outpict = imblend(fgimage,bgimage,1,'normal','linear'); % compose
outpict = splitalpha(outpict); % strip extraneous alpha channel
% draw things
imshow(outpict)
It's not the greatest, but the rasterized contour image was pretty terrible to begin with. The tools used in this example (color2alpha(), imblend(), and splitalpha()) are part of MIMT (on the File Exchange).
For other blending/composition examples, see this answer and the links therein. Those answers cover techniques based on MATLAB/IPT tools, as well as techniques based on MIMT tools.
0 Comments
David Young
on 14 Jul 2016
You can use hold to superimpose contour lines on an image. Here's an example:
% Get an image from a jpg file
img = imread('street1.jpg');
% display it
imshow(img);
% superimpose a contour map (in this case of the image brightness)
hold on;
contour(rgb2gray(img), 5);
hold off;
2 Comments
ted as
on 9 Apr 2017
hello this is my first question in mathworks . im trying to analyse via fft some data but due to the fact that i have some gaps in my measurements and since i have one measurement every 30 min i'm having hard time to do that correct. thank you in advace ! Ted
Image Analyst
on 9 Apr 2017
What do you want to do with the rows that have missing measurements? Ignore them? Interpolate them?
See Also
Categories
Find more on 3-D Volumetric Image Processing in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!