Create a bitmap from patch object in Matlab

◇◆丶佛笑我妖孽 提交于 2019-12-11 09:31:25

问题


I have a set of polygon vertices in in X, Y matrices and their colors are in RGB values in another matrix C.

I then use fill() function to generate patch objects that is displayed in a Matlab figure.

I want to create a bmp object from this figure. What I mean by a bmp object is the x,y coordinates of the pixels and there RGB values.

If I use the print() function, with '-dbmp' and a file name, matlab can write the bmp to a file. But then I have to read the file with imread() to create the bmp object.

Is there a way to create the bmp object without writing and reading to from a file?

Becauswe I have to perform this operation many times and writing and reading to file is time consuming and will reduce the life time of my disk too I guess.

Edit: code after editing according to answer

N = 5;
Tri = 100;
res = 200; %200 pixles per inch
G = zeros(Tri,9,N);


X = 2*rand(Tri,3,N);
Y = 2*rand(Tri,3,N);
R = randi([0 255],Tri,N)/255;
G = randi([0 255],Tri,N)/255;
B = randi([0 255],Tri,N)/255;

for c1=1:N
   G(:,1:3,c1)= X(:,:,c1);
    G(:,4:6,c1)= Y(:,:,c1);
    G(:,7,c1)= R(:,c1);
    G(:,8,c1)= G(:,c1);
    G(:,9,c1)= B(:,c1);

end

for c2=1:N;
    h = figure('Visible','off');
    set(h, 'PaperUnits', 'inches', 'PaperPosition', [0 0 400 400]/res);
    for c3 =1:Tri
        h1 = fill(G(c3,1:3,c2), G(c3,4:6,c2), [G(c3,7,c2) G(c3,8,c2) G(c3,9,c2)]);
        set(h1,'EdgeColor','None');
        hold on;
    end
    %print(h,'-dbmp',['-r' num2str(res)],['file' num2str(c2)]);
    F = getframe(h);
    [a, b] = frame2im(F);

    Tmp_v1 =  a;
    Tmp_v1 = Tmp_v1(:);
    Norm_v1(c2) = norm(single(Tmp_v1));
end

Thank you.


回答1:


If you have the current figure open, you can try the getframe idiom. Once you have access to this, you can access the frame's image data by looking at the cdata field in the structure. After you have this, you can use the imwrite command from MATLAB's image processing toolbox (let's hope you have it...) to write the image to file.

Here's an example:

x = 1 : 5;
y = 1 : 5;
plot(x,y); %// Plot a line
h = getframe;
img = h.cdata;
imwrite(img, 'testFrame.bmp');

This should be able to grab what is inside the current figure and save it to file. In this case, this will be a straight line from (x,y) = (1,1) to (x,y) = (5,5), with a slope of 1. Bear in mind that this won't save the title of the graph or the axes. This will only grab what is rendered inside the frame.


Edit from comments

Now that I know what you're really after, you want to generate a bunch of random polygons, then extract just the core image, without any axes or tick marks and so on. You'll have to modify your for loop where you're creating the images so that you want the figure to fill the entire window without any gray padding You'll also want to turn off the axis too. Also, when you're generating each image, you'll need to turn off the ticks. This is done with a combination of not writing any tick labels, as well as setting the tick length to 0. In other words, you'll need to modify your code so that it looks like this. You'll see where I inserted code by seeing the %// NEW statements in your code:

for c2=1:N;
    h = figure('Visible','off');
    subplot('position', [0 0 1 1]); %// NEW
    axis off; %// NEW
    set(h, 'PaperUnits', 'inches', 'PaperPosition', [0 0 400 400]/res);
    for c3 =1:Tri
        h1 = fill(G(c3,1:3,c2), G(c3,4:6,c2), [G(c3,7,c2) G(c3,8,c2) G(c3,9,c2)]);
        set(h1,'EdgeColor','None');
        set(gca,'xcolor','w','ycolor','w','xtick',[],'ytick',[]) %// NEW
        set(gca,'Ticklength',[0 0]); %// NEW
        hold on;
    end
    %print(h,'-dbmp',['-r' num2str(res)],['file' num2str(c2)]);

    F = getframe(h);
    close all; %// NEW
    [a, b] = frame2im(F);
    a = imresize(a, [400 400], 'nearest'); %// NEW

    Tmp_v1 =  a;
    Tmp_v1 = Tmp_v1(:);
    Norm_v1(c2) = norm(single(Tmp_v1));
end

This will still show you the frames being popped up for each image you're creating, but you should be able to get just pure image data at this point. Note that the images are still coming out as a bit larger than 400 x 400. This is due to the fact that once we have removed the borders and the tick marks and so on, the figure will stretch to fill the entire figure. To get around this, I use imresize and shrink the images back down to 400 x 400 as per your desired size.

Also, take note that every time you generate a new image, a new figure is spawned. Every time you call getframe, the figure with this randomly generated polygon image pops up, and getframe takes a snapshot of that current frame. There isn't a way to prevent this from happening, as you won't be able to take a snapshot of that figure. One way to get around this would be to close the figure after you grab the image. You can do a close all; after each call to getframe. That way, only one figure gets shown at any one time, but this still won't prevent the figure from showing up.

If I do find a solution to this, I'll let you know!



来源:https://stackoverflow.com/questions/25725408/create-a-bitmap-from-patch-object-in-matlab

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!