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 read the image with:
W=double(imread('rose32.bmp'));
Then:
imshow(W,[]);
or
imshow(W);
But the shown image seems to be inverted with respect to the original image. How can I solve this problem ? Is it a MATLAB problem?
The problem is probably caused by the formatting the the imagefile!
When you use imread what it returns depends of the formatting of the image in the image file. imread returns tree values [A,map,transparency] = imread(___), where A might be hxw-matrix or a hxwx3-matrix (h and w are short for height and width) of several different possible classes (eg. double or uint8).
In the case of the hxwx3-matrix the output-variable map will be empty, and you can show the image directly using imshow(A). This is called an RGB-image.
The other possibility (called an indexed image) is the hxw-matrix. In this case map is a colormap, and you can show the image by imshow(A,map).
You can easily convert between these two types of images by ind2rgb(A,map) and rgb2ind(A).
The other thing you need to be careful with is the class of the image.
If you have an rgb-image of class uint8, then the values of image will be integers between 0 and 255, whereas rgb-images of type double have values between 0 and 1. You should never convert an image to double-class by the double-function like you do; in stead use im2double.
So to solve your problem try the following code:
[img,map] = imread('rose32.bmp');
if ~isempty(map)
img = ind2rgb(img,map);
end
img = im2double(img);
Now imshow(img) should show the image correctly. Or you can simply use the following code:
[W,map] = imread('rose32.bmp');
imshow(W,map);
I have a 3 dimension matrix of data (a stack of images across a dimension, time for example.
I want to display an image, and have a slider below to navigate across the images.
I wrote a piece of code which works, but it's bulky and kinda ugly I think...I want to write a clean function and so I would like to know if anyone know of a cleaner, nicer way to do it.
Here is my code:
interv = [min max]; % interval for image visualization
imagesc(Temps_visu,X*100,squeeze(X,Y,MyMatrix(:,:,1)),interv);
title('My Title');
xlabel('X (cm)');
ylabel('Y (cm)');
pos = get(gca,'position');
% slider position
Newpos = [pos(1) pos(2)-0.1 pos(3) 0.05];
pp = 1;
% callback slider
S = ['pp=floor(get(gcbo,''value''));imagesc(Temps_visu,X*100,squeeze(X,Y,MyMatrix(:,:,1)),interv));' ...
'set_axes_elasto;title(''My Title'');disp(pp);'];
Mz = size(MyMatrix,3);
% Creating Uicontrol
h = uicontrol('style','slider',...
'units','normalized',...
'position',Newpos,...
'callback',S,...
'min',1,'max',Mz,...
'value',pp,...
'sliderstep',[1/(Mz-1) 10/(Mz-1)]);
Here is a way to do it using a listener object for smooth visualization of your stack. I made up a dummy stack using grayscale variations of the same image (i.e. only 4 frames) but the principle will be the same for your application. Notice that I use imshow to display the images, but using imagesc as you do won't cause any problem.
The code is commented so hopefully this is clear enough. If not please don't hesitate to ask for help!
Code:
function SliderDemo
clc
clear all
NumFrames = 4; %// Check below for dummy 4D matrix/image sequence
hFig = figure('Position',[100 100 500 500],'Units','normalized');
handles.axes1 = axes('Units','normalized','Position',[.2 .2 .6 .6]);
%// Create slider and listener object for smooth visualization
handles.SliderFrame = uicontrol('Style','slider','Position',[60 20 400 50],'Min',1,'Max',NumFrames,'Value',1,'SliderStep',[1/NumFrames 2/NumFrames],'Callback',#XSliderCallback);
handles.SliderxListener = addlistener(handles.SliderFrame,'Value','PostSet',#(s,e) XListenerCallBack);
handles.Text1 = uicontrol('Style','Text','Position',[180 420 60 30],'String','Current frame');
handles.Edit1 = uicontrol('Style','Edit','Position',[250 420 100 30],'String','1');
%// Create dummy image sequence, here 4D sequence of grayscale images.
MyImage = imread('peppers.png');
MyMatrix = cat(4,rgb2gray(MyImage),MyImage(:,:,1),MyImage(:,:,2),MyImage(:,:,3));
%// Use setappdata to store the image stack and in callbacks, use getappdata to retrieve it and use it. Check the docs for the calling syntax.
setappdata(hFig,'MyMatrix',MyMatrix); %// You could use %//setappdata(0,'MyMatrix',MyMatrix) to store in the base workspace.
%// Display 1st frame
imshow(MyMatrix(:,:,:,1))
%// IMPORTANT. Update handles structure.
guidata(hFig,handles);
%// Listener callback, executed when you drag the slider.
function XListenerCallBack
%// Retrieve handles structure. Used to let MATLAB recognize the
%// edit box, slider and all UI components.
handles = guidata(gcf);
%// Here retrieve MyMatrix using getappdata.
MyMatrix = getappdata(hFig,'MyMatrix');
%// Get current frame
CurrentFrame = round((get(handles.SliderFrame,'Value')));
set(handles.Edit1,'String',num2str(CurrentFrame));
%// Display appropriate frame.
imshow(MyMatrix(:,:,:,CurrentFrame),'Parent',handles.axes1);
guidata(hFig,handles);
end
%// Slider callback; executed when the slider is release or you press
%// the arrows.
function XSliderCallback(~,~)
handles = guidata(gcf);
%// Here retrieve MyMatrix using getappdata.
MyMatrix = getappdata(hFig,'MyMatrix');
CurrentFrame = round((get(handles.SliderFrame,'Value')));
set(handles.Edit1,'String',num2str(CurrentFrame));
imshow(MyMatrix(:,:,:,CurrentFrame),'Parent',handles.axes1);
guidata(hFig,handles);
end
end
The figure looks like this:
Hope that helps!
I have an image that is saved in a database. I need a script that can read the RGB + x and y value of each pixel of this image.
This is needed because I want to be able to show random pixels of this image in a browser. With random I mean, random positions. The number of pixels is selected with a form. When the form is used, a number of pixels of the image will be visible in the browser and this new image will be saved. The next time the form is used, the new image with a few pixels visible, will be displayed in the browser. And so on.... each time the form is used, the image will get more and more visible.
I did some testing with the PHP GD library, but not been able to extract the RGB as well as the position of each pixel. For outputting an array of RGBA vallues, I used this how to count number of pixels in image (php). But as you see, this is just the beginning.
$img = "images/test.png";
$imgHand = imagecreatefrompng("$img");
$imgSize = GetImageSize($img);
$imgWidth = $imgSize[0];
$imgHeight = $imgSize[1];
// Define a new array to store the info
$pxlCorArr= array();
for ($l = 0; $l < $imgHeight; $l++) {
// Start a new "row" in the array for each row of the image.
$pxlCorArr[$l] = array();
for ($c = 0; $c < $imgWidth; $c++) {
$pxlCor = ImageColorAt($imgHand,$c,$l);
// Put each pixel's info in the array
$pxlCorArr[$l][$c] = ImageColorsForIndex($imgHand, $pxlCor);
}
}
do you want a partial image to be shown and then full image ? or random part of it ?
take a look at this ,
https://github.com/ogres/Image2HTML
it will convert an image to html table , you could edit it so only random part of image will be shown
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.