I want to extract only red rose. The following code is okay, but it does not extract. So, please help!
Image = imread('red_rose.jpeg');
mask = Image(:,:,2)<Image(:,:,1) & Image(:,:,3)<Image(:,:,1);
Red_Image = bsxfun(#times, Image, uint8(mask));
imshow(Red_Image);
Related
I have a 4-channel image (.png, .tif) like this one:
I am using OpenCV, and I would like to add padding of type BORDER_REFLECT around the flower. copyMakeBorder is not useful, since it adds padding to the edges of the image.
I can add certain padding if I split the image in bgr + alpha and apply dilate with BORDER_REFLECT option on the bgr image, but that solution spoils all the pixels of the flower.
Is there any way to perform a selective BORDER_REFLECT padding addition on a ROI defined by a binary mask?
EDIT:
The result I expect is something like (sorry I painted it very quickly with GIMP) :
I painted two black lines to delimit the old & new contour of the flower after the padding, but of course those lines should not appear in the final result. The padding region (inside the two black lines) must be composed by mirrored pixels from the flower (I painted it yellow to make it understandable).
A simple python script to resize the image and copy the original over the enlarged one will do the trick.
import cv2
img = cv2.imread('border_reflect.png', cv2.IMREAD_UNCHANGED)
pad = 20
sh = img.shape
sh_pad = (sh[0]+pad, sh[1]+pad)
imgpad = cv2.resize(img, sh_pad)
imgpad[20:20+sh[0], 20:20+sh[1], :][img[:,:,3]==255] = img[img[:,:,3]==255]
cv2.imwrite("padded_image.png", imgpad)
Here is the result
But that doesn't look very 'centered'. So I modified the code to detect and account for the offsets while copying.
import cv2
img = cv2.imread('border_reflect.png', cv2.IMREAD_UNCHANGED)
pad = 20
sh = img.shape
sh_pad = (sh[0]+pad, sh[1]+pad)
imgpad = cv2.resize(img, sh_pad)
def get_roi(img):
cimg = img[:,:,3].copy()
contours,hierarchy = cv2.findContours(cimg,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#Remove the tiny pixel noises that get detected as contours
contours = [cnt for cnt in contours if cv2.contourArea(cnt) > 10]
x,y,w,h = cv2.boundingRect(cnt)
roi=img[y:y+h,x:x+w]
return roi
roi = get_roi(img)
roi2 = get_roi(imgpad)
sh = roi.shape
sh2 = roi2.shape
o = ((sh2[0]-sh[0])/2, (sh2[1]-sh[1])/2)
roi2[o[0]:o[0]+sh[0], o[1]:o[1]+sh[1], :][roi[:,:,3]==255] = roi[roi[:,:,3]==255]
cv2.imwrite("padded_image.png", imgpad)
Looks much better now
The issue has been already addressed and solved here:
http://answers.opencv.org/question/90229/add-padding-to-object-in-4-channel-image/
I wish to skeletonize this image
To do so i am using matlab's bwmorph function, Here is the snippet :
bw = bwmorph(img_bw,'skel',Inf);
However the output is not as expected. Here is the output.
Could someone suggest a better way to achieve proper results ?
EDIT: here is a stripped down relevant code
img = imread(name);
img = rgb2gray(img*4);
img_bw = img > 50;
img_bw = medfilt2(img_bw,[10 10]);
bw = bwmorph(img_bw,'skel',Inf);
What you see is aliasing, the imshow function can not display the full image because it is to large to fit the screen. To fit the screen some rows and columns are skipped, which cause the lines to be disconnected. To display an image at full resolution using a scrollpanel, use imscrollpanel
hFig = figure('Toolbar','none', 'Menubar','none');
hIm = imshow(bw);
hSP = imscrollpanel(hFig,hIm);
I have an image I that I want to save with axes on it.
imwrite(I,jet,'image.jpg');
will save the image.
I = image;
RI = imref2d(size(I));
RI.XWorldLimits = [xmin xmax];
RI.YWorldLimits = [ymin ymax];
figure(1);
imshow(I,RI,jet);
xlabel('x');
ylabel('y');
print(1,'-djpeg','image.jpg');
will plot the image with axes on a figure and then save it with axes.
I want to save the image with axes, without plotting it in a figure first. Is there a way to do this?
If what you want is for the figure not to be seen by the user, the easiest way is to create the figure and set its 'visible' property to 'off':
I = image;
RI = imref2d(size(I));
RI.XWorldLimits = [xmin xmax];
RI.YWorldLimits = [ymin ymax];
figure(1);
set(1,'visible','off') %// add this line to make figure not visible
imshow(I,RI,jet);
xlabel('x');
ylabel('y');
print(1,'-djpeg','image.jpg');
I am modifying images in matlab and I have a problem.
I need to separate the 3 channels of color and modify them separately.
I use this to obtain the three channels:
a = imread('./images/penguins.png');
colorlist = {'R','G','B'};
subplot(2,2,1);
imshow(a);
for k=1:3
subplot(2,2,k+1);
imshow( a(:,:,k));
title(colorlist{k});
end
a(:,:,k) is one color of the three. The problem is when I add the three vectors in one, to obtain the color image. I do this:
A=a(:,:,1)+a(:,:,2)+a(:,:,3)
figure; imshow(A);
But it dont works, it only show me a very highlight image, no a color image.
Anyone knows how can I recover the color image? Thanks for yout help^^
You are adding the values of the three layers instead of concatenating them in a 3D array.
Try this:
A= cat(3, a(:,:,1), a(:,:,2), a(:,:,3));
I should also note that you can edit the layers simply by indexing, say you want to switch the red and green components:
I1 = imread('http://i.stack.imgur.com/1KyJA.jpg');
I2=I1;
I2(:,:,1)=I1(:,:,2);
I2(:,:,2)=I1(:,:,1);
imshowpair(I1,I2, 'montage');
Now if I take your title literally, let's say you do want to add the three layers and display the result with a colormap, you can do:
A=a(:,:,1)+a(:,:,2)+a(:,:,3)
imagesc(A); axis image;
colorbar;
Results:
Let's say my image is img=zeros(100,100,3), my outputs are several ellipse which i get using a created function [ret]=draw_ellipse(x,y,a,b,angle,color,img), I can display one ellipse using imshow(ret).For the moment, I'm trying to show serval ellipse in the image. But i don't know how to code it. will ‘for loop’ work or I need to hold them?
If this is related to what you were doing in your previous question, then what you need to do is to pass the result of one iteration as input to the next.
So assuming that the function [ret]=draw_ellipse(x,y,a,b,angle,color,img) you mentioned takes as input an image img and returns the same image with an ellipse drawn on it, you could do this:
%# ellipses parameters
%#x = {..}; y = {..};
%#a = {..}; b = {..};
%#angle = {..}; color = {..};
img = zeros(200,100,'uint8'); %# image to start with
for i=1:10
img = draw_ellipse(x{i},y{i}, a{i},b{i}, angle{i}, color{i}, img);
end
imshow(img)
I'm a bit unsure of what you want. You want to show several ellipse in one image, like plotting several graphs with hold on?
There is no equivalent command for images, but a simple solution is to add the ellipses into one image and show that one:
several_ellipse = ellipse1 + ellipse2 + ellipse3;
imshow(several_ellipse)
Presumably you want to pass ret as the final input to the next call to draw_ellipse.