matlab 3d projection image - image

I'm doing a image 3D projection, but when I use the iwarp function the result is a multidimensional matrix, I'm using:
color1 = imread('color1.jpg') % 480x640x3 image RBG
%4X4 projection matrix
Mx = makehgtform('xrotate',-0.01970);
My = makehgtform('yrotate',0.01729);
Mz = makehgtform('zrotate',-0.00717);
M = Mx*My*Mz;
M(1,4) = -28.54007;
M(2,4) = -2.00470;
M(3,4) = 4.37353;
T = affine3d(M);
%Do transform
Color_Rectified = imwarp(color1,T); %485X644x24
At the end, the Color_Rectified size is 485X644x24, the idea is to get the image rotated/translated in X,Y,Z and RGB, how to do this?

Related

How to do I apply the same augmentations to two sets of similar data

I am trying to train an image translation model with TensorFlow, the dataset consists of two equal length list of images, how do I apply a map both of them so they receive the same augmentations.
I have tried to create a variable to keep track of which iteration it is, as well as using a seeded random number.
def load_and_preprocess_color(path):
image = tf.read_file(path)
image = tf.image.decode_png(image, channels=3)
image = tf.image.resize(image, [224, 224])
image = tf.image.random_flip_left_right(image)
image /= 255.0 # normalize to [0,1] range
return image
def load_and_preprocess_gray(path):
image = tf.read_file(path)
image = tf.image.decode_png(image, channels=1)
image = tf.image.resize(image, [224, 224])
image = tf.image.random_flip_left_right(image)
image /= 255.0 # normalize to [0,1] range
return image
input_data_root = pathlib.Path('Images/Gray/') output_data_root =
pathlib.Path('Images/Color/')
input_image_paths = [str(item) for item in input_data_root.iterdir()]
output_image_paths = [str(item) for item in
output_data_root.iterdir()] image_count = len(input_image_paths)
input_path_ds = tf.data.Dataset.from_tensor_slices(input_image_paths)
output_path_ds =
tf.data.Dataset.from_tensor_slices(output_image_paths)
input_ds =
input_path_ds.map(load_and_preprocess_gray,num_parallel_calls=AUTOTUNE)
output_ds =
output_path_ds.map(load_and_preprocess_color,num_parallel_calls=AUTOTUNE`
I expect two pieces of data at the same position to be either flipped of not flipped, but its flipped state to be the same as the other

Overlapping grayscale and RGB Images

I would like to overlap two images, one grayscale and one RGB image. I would like to impose the RGB image on top of the grayscale image, but ONLY for pixels greater than a certain value. I tried using the double function in MATLAB, but this seems to change the color scheme and I cannot recover the original RGB colors. What should I do in order to retain the original RGB image instead of mapping it to one of the MATLAB colormaps? Below is my attempt at superimposing:
pixelvalues = double(imread('hello.png'));
PixelInt = mean(pixelvalues,3);
I1 = ind2rgb(Brightfield(:,:,1), gray(256)); %Brightfield
I2 = ind2rgb(PixelInt, jet(256)); %RGB Image
imshow(I2,[])
[r,c,d] = size(I2);
I1 = I1(1:r,1:c,1:d);
% Replacing those pixels below threshold with Brightfield Image
threshold = 70;
I2R = I2(:,:,1); I2G = I2(:,:,2); I2B = I2(:,:,3);
I1R = I1(:,:,1); I1G = I1(:,:,2); I1B = I1(:,:,3);
I2R(PixelInt<threshold) = I1R(PixelInt<threshold);
I2G(PixelInt<threshold) = I1G(PixelInt<threshold);
I2B(PixelInt<threshold) = I1B(PixelInt<threshold);
I2(:,:,1) = I2R; I2(:,:,2) = I2G; I2(:,:,3) = I2B;
h = figure;
imshow(I2,[])
Original RGB Image:
Brightfield:
Overlay:
Is the content of pixelvalues what you show in your first image? If so, that image does not use a jet colormap. It has pink and white values above the red values, whereas jet stops at dark red at the upper limits. When you take the mean of those values and then generate a new RGB image with ind2rgb using the jet colormap, you're creating an inherently different image. You probably want to use pixelvalues directly in generating your overlay, like so:
% Load/create your starting images:
pixelvalues = imread('hello.png'); % Color overlay
I1 = repmat(Brightfield(:, :, 1), [1 1 3]); % Grayscale underlay
[r, c, d] = size(pixelvalues);
I1 = I1(1:r, 1:c, 1:d);
% Create image mask:
PixelInt = mean(double(pixelvalues), 3);
threshold = 70;
mask = repmat((PixelInt > threshold), [1 1 3]);
% Combine images:
I1(mask) = pixelvalues(mask);
imshow(I1);
Note that you may need to do some type conversions when loading/creating the starting images. I'm assuming 'hello.png' is a uint8 RGB image and Brightfield is of type uint8. If I load your first image as pixelvalues and your second image as I1, I get the following when running the above code:
Create a mask and use it to combine the images:
onionOrig = imread('onion.png');
onionGray = rgb2gray(onionOrig);
onionMask = ~(onionOrig(:,:,1)<100 & onionOrig(:,:,2)<100 & onionOrig(:,:,3)<100);
onionMasked(:,:,1) = double(onionOrig(:,:,1)) .* onionMask + double(onionGray) .* ~onionMask;
onionMasked(:,:,2) = double(onionOrig(:,:,2)) .* onionMask + double(onionGray) .* ~onionMask;
onionMasked(:,:,3) = double(onionOrig(:,:,3)) .* onionMask + double(onionGray) .* ~onionMask;
onionFinal = uint8(onionMasked);
imshow(onionFinal)

Resize a polygon image in matlab

I have two polygon images defined by 25 control points. I want to replace one polygon by another one in matlab. Below is an example of TC and BP.
I have added the code. I am not happy with the output texture in the replaced area. Also, I found the that if the polygon shape of the second image is smaller than the first image polygon shape then the output looks very bad.
clc;clear all;close all
im_original = imread('tc.jpg');
im_original=im2double(im_original);
%% ROI (X,Y) coordinates, variable name (pt_original)
load('tc.mat');
im_morphed = imread('bp.jpg');
img_morphed=im2double(im_morphed);
%% ROI (X,Y) coordinates, variable name (pt_morphed)
load('bp.mat');
%% Replace Face
[img_proc,mask] = defineRegion(im_original,pt_original);
img_morphed_proc = histeq_rgb(img_morphed, im_original, mask, mask);
sigma = 5;
se = strel('square',sigma);
mask = imerode(mask,se);
w = fspecial('gaussian',[50 50],sigma);
mask = imfilter(double(mask),w);
img_result = bsxfun(#times,double(img_morphed_proc),double(mask)) + bsxfun(#times,double(im_original),double(1-mask));
imshow(img_result)
function [img_proc,mask] = defineRegion(img, landmark)
sz = size(img);
k =convhull(landmark(:,2),landmark(:,1));
[YY,XX] = meshgrid(1:sz(1),1:sz(2));
in = inpolygon(XX(:),YY(:),landmark(k,1),landmark(k,2));
mask = reshape(in,[sz(2),sz(1)])';
img_proc = bsxfun(#times,im2double(img),double(mask));
end
function img_proc = histeq_rgb(img_src, img_dest, mask_src, mask_dest)
img_proc = img_src;
for i = 1 : 3
tmp_src = img_src(:,:,i);
tmp_src = tmp_src(mask_src);
tmp_dest = img_dest(:,:,i);
tmp_dest = tmp_dest(mask_dest);
t = histeq(tmp_src,imhist(tmp_dest));
tmp_proc = img_proc(:,:,i);
tmp_proc(mask_src) = t;
img_proc(:,:,i) = tmp_proc;
end
end
Output Image

No display from using subplot after wavedec2 in MATLAB

I followed the MathWorks tutorial on wavedec2 and am unable to properly display any of the coefficient or approximation subplots.
Can anyone suggest how I fix this so it displays the approximation and detail subplots correctly?
This is what I have so far:
% Load image ‘Sample.tif’ and convert it into a grayscale image, denoted with ‘img1’
I = imread('Sample.tif');
img1 = rgb2gray(I);
% Decompose img1 with wavelet transform using function wavedec2
% Perform decomposition at level 2
% of X using haar.
[C,S] = wavedec2(I,2,'haar');
[H1,V1,D1] = detcoef2('all',C,S,1);
A1 = appcoef2(C,S,'haar',1);
V1img = wcodemat(V1,255,'mat',1);
H1img = wcodemat(H1,255,'mat',1);
D1img = wcodemat(D1,255,'mat',1);
A1img = wcodemat(A1,255,'mat',1);
[H2,V2,D2] = detcoef2('all',C,S,2);
A2 = appcoef2(C,S,'haar',2);
V2img = wcodemat(V2,255,'mat',1);
H2img = wcodemat(H2,255,'mat',1);
D2img = wcodemat(D2,255,'mat',1);
A2img = wcodemat(A2,255,'mat',1);
subplot(2,2,1);
imagesc(A1img);
colormap red(255);
title('Approximation Coef. of Level 1');
subplot(2,2,2);
imagesc(H1img);
title('Horizontal detail Coef. of Level 1');
subplot(2,2,3);
imagesc(V1img);
title('Vertical detail Coef. of Level 1');
subplot(2,2,4);
imagesc(D1img);
title('Diagonal detail Coef. of Level 1');
The output is here, and all subplots are completely white:
Sample.tif is here:
The datatype of your images is double but the range of value of your images is [0 255] so you have to cast your picture into the good datatype. [0 255] correspond to the range of the uint8 datatype, so you can simply write:
imagesc(uint8(A1img));
or
A1img = uint8(A1img);

Connect disjoint edges in binary image

I performed some operations on an image of a cube and I obtained a binary image of the edges of the cube which are disconnected at some places.The image I obtained is shown below:
I want to join the sides to make it a closed figure.I have tried the following:
BW = im2bw(image,0.5);
BW = imdilate(BW,strel('square',5));
figure,imshow(BW);
But this only thickens the image.It does not connect the edges.I have also tried bwmorph() and various other functions, but it is not working.Can anyone please suggest any function or steps to connect the edges? Thank you
This could be one approach -
%// Read in the input image
img = im2bw(imread('http://i.imgur.com/Bl7zhcn.jpg'));
%// There seems to be white border, which seems to be non-intended and
%// therefore could be removed
img = img(5:end-4,5:end-4);
%// Thin input binary image, find the endpoints in it and connect them
im1 = bwmorph(img,'thin',Inf);
[x,y] = find(bwmorph(im1,'endpoints'));
for iter = 1:numel(x)-1
two_pts = [y(iter) x(iter) y(iter+1) x(iter+1)];
shapeInserter = vision.ShapeInserter('Shape', 'Lines', 'BorderColor', 'White');
rectangle = int32(two_pts);
im1 = step(shapeInserter, im1, rectangle);
end
figure,imshow(im1),title('Thinned endpoints connected image')
%// Dilate the output image a bit
se = strel('diamond', 1);
im2 = imdilate(im1,se);
figure,imshow(im2),title('Dilated Thinned endpoints connected image')
%// Get a convex shaped blob from the endpoints connected and dilate image
im3 = bwconvhull(im2,'objects',4);
figure,imshow(im3),title('Convex blob corresponding to previous output')
%// Detect the boundary of the convex shaped blob and
%// "attach" to the input image to get the final output
im4 = bwboundaries(im3);
idx = im4{:};
im5 = false(size(im3));
im5(sub2ind(size(im5),idx(:,1),idx(:,2))) = 1;
img_out = img;
img_out(im5==1 & img==0)=1;
figure,imshow(img_out),title('Final output')
Debug images -
I used the above code to write the following one.I haven't tested it on many images and it may not be as efficient as the one above but it executes faster comparatively.So I thought I would post it as a solution.
I = imread('image.jpg'); % your original image
I=im2bw(I);
figure,imshow(I)
I= I(5:end-4,5:end-4);
im1 = bwmorph(I,'thin',Inf);
[x,y] = find(bwmorph(im1,'endpoints'));
for iter = 1:numel(x)-1
im1=linept(im1, x(iter), y(iter), x(iter+1), y(iter+1));
end
im2=imfill(im1,'holes');
figure,imshow(im2);
BW = edge(im2);
figure,imshow(BW);
se = strel('diamond', 1);
im3 = imdilate(BW,se);
figure,imshow(im3);
The final result is this:
I got the "linept" function from here:http://in.mathworks.com/matlabcentral/fileexchange/4177-connect-two-pixels

Resources