help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: getframe() alternatives


From: Cameron MacArthur
Subject: Re: getframe() alternatives
Date: Fri, 30 Aug 2013 11:54:45 -0400

 

----- Original Message -----

From: Philip Nienhuis

Sent: 08/30/13 04:33 AM

To: Cameron MacArthur

Subject: Re: getframe() alternatives

 
Hi Cameron, 

First a few things: 

1. Please do not top post; always answer BELOW the text, or below 
relevant stanzas, because that way discussions are a lot easier to 
follow for other people. I already asked you this before: 
https://mailman.cae.wisc.edu/pipermail/help-octave/2013-August/060006.html 
so please comply. 

2. Please include the Octave Help mailing list, so others can benefit 
from the discussion as well. 

3. The whole getframe.m I sent is a kludge (not such a bad one I'd say) 
supplied without any guarantee; I'll help you below but I'm not going to 
spend much time/priority on it. If it doesn't work right away you really 
have to sort out a few things yourself, or wait until someone sometime 
somewhere comes up with a better solution. 

Read on... 

Cameron MacArthur wrote: 
> Philip, 
> I added what you sent me to my code, now it looks like this where the 
> hardcopy stuff was: 
> print (h,'tmp.fig','dppm'); 
> ret = im2double (imread ('tmp.fig')); 
> % Truncate to even size to accomodate addframe() 
> if (mod (size (ret, 1), 2) > 0); ret = ret(2:end, :, :); endif 
> if (mod (size (ret, 2), 2) > 0); ret = ret(:, 2:end, :); endif 
> mov = addframe(mov,ret); 
> end 
> but I keep getting the error in Octave: 
> reading contents of C:\Users\Administrator\Desktop\SanDisk\FTS...done. 
> rendering frames... 
> *error: imread: cannot find tmp.fig* 

That is a clear message isn't it: imread() cannot find the (temporary) 
file tmp.fig where it expects it to be. 
I suppose the -in this case!- most obvious cause is that tmp.fig simply 
hasn't been created, i.e. the print() command a few lines higher up has 
failed. 

Now, the usual attack vector for this sort of issues is to try to 
manually execute the commands in the getframe.m function one by one to 
find out what fails where. Just copy or type the lines into the Octave 
terminal. 

If print() fails, it may be due to a lot of potential issues. 
But in this case I really suspect you haven't got Ghostscript (properly) 
installed such that Octave can find it; I think so because the "device" 
type "ppm" requires Ghostscript, and AFAIR print() doesn't error out but 
merely warns when Ghostscript isn't found. Execution continues then 
until a next command that relies on print()'s output gets into trouble 
and gives up. 
If so, you can also experiment with other devices rather than with ppm: 
try "emf", "gif", "svg", etc to find out which one works, or even which 
one works the best. Do a "help print" to see what is exactly needed. 

It may also be handy, just for reference, to show us what commands are 
used to make the movie. 
Only show these commands: 
- the call to avifile to create the movie; 
- how you create the figure and save its handle 
  <...just skip all the pimping & polishing of your graphics...> 
- how you invoke getframe.m 
- how you call addframe() to add the frame to the movie. 

Philip 

> -Cameron 
> 
>> ----- Original Message ----- 
>> 
>> From: Philip Nienhuis 
>> 
>> Sent: 08/19/13 06:15 PM 
>> 
>> To: address@hidden 
>> 
>> Subject: Re: getframe() alternatives 
>> 
>> <help-octave ML added, other people can benefit as well> 
>> 
>> address@hidden wrote: 
>> >  Philip, 
>> > 
>> >  I saw your "getframe() alternatives" post and got very excited because I've been trying to do exactly the same thing.  I have a matlab function that takes pictures overlayed with scatterplot data and makes it into a video.  The function uses the matlab function "hardcopy" at the end to make the video like this: 
>> >  % add this frame to movie file 
>> >       %mov = addframe(mov,gcf); 
>> >       renderer = get(hnd,'renderer'); 
>> >       if strcmp(renderer,'painters') 
>> >           renderer = 'opengl'; 
>> >       end 
>> >       set(hnd, 'Units', 'pixels'); 
>> >       pixelsperinch = get(0,'screenpixelsperInch'); 
>> > 
>> >       frame = hardcopy(hnd, ['-d' renderer], ['-r' num2str(round(pixelsperinch))]); 
>> >       addframe(mov,frame); 
>> > 
>> >  but Octave can't understand hardcopy, so I tried to replace it with just: 
>> >  addframe(mov,gcf); 
>> > 
>> >  but I get error: addframe: input frame should be in [0-1] 
>> > 
>> >  I saw your post and was hoping you could help me.  I'm a super matlab and Octave novice (like, yesterday) and I'm trying to make this matlab function work in octave for a collegue. 
>> >  Would you help me implement your solution to this problem for octave? 
>> >  (I tried adding this via your post:) 
>> >  HH = im2double (imread (gcf)); 
>> >     aviobj = addframe (aviobj, HH); 
>> > 
>> >  but Octave doesn't like that either. 
>> > 
>> >  Any help you can give would be super appreciated.  Thanks for your time. 
>> 
>> Currently I have no time; maybe tomorrow night (but I doubt it). 
>> 
>> Just a quick answer: gcf is a figure handle, isn't it? If so, you can't 
>> use that by adding it to the movie. It is a mere double (actually 
>> disguised as a figure handle). 
>> 
>> You'd need to prepare a color bitmap for each movie frame and add that 
>> to the movie. 
>> I created the bitmaps by printing each picture to file, then reading it 
>> using imread into a bitmap and feed that to aviobj. All steps but the 
>> last one were done in an .m-file (attached). 
>> Each frame took ~20 secs to write and read; clumsily yes, but OK it 
>> worked. On my current "power"box at work I think it should go much 
>> faster (it has an SSD). 
>> 
>> What we actually need is a binary getframe that makes a snapshot of the 
>> current figure and turns it into a bitmap. I've looked into it a while 
>> back it but got lost in the OpenGL and fltk sources. 
>> 
>> Anuway I'll attach my old getframe.m to this mail. 
>> 
>> Philip 
>

Philip,

 
Thanks again for getting back to me, I really appreciate all of your help, and the patience you've had with my ignorance about all of this.
 
1. Sorry, but I'm not sure what you mean by "top post".  I just hit "reply" to the email, should I respond a different way i.e through the forum etc?  Or scroll to the bottom of the email and respond here like I've done this time?
 
2.  My apologies again, I've hit "reply all" now and included the mailing list
 
3. I totally understand.  I really appreciate what you've done to help thus far, but I entirely recognize that you can't spend all of your time helping a newbie figure out Octave.
 
On your comments,
 
I tried copying and pasting the lines one-by-one into the command prompt, but the print statement, imread etc, is all in a larger loop with the code above it that overlays a scatterplot over each frame, so I just return the error once I finish typing the loop.  I'm positive that ghostscript is installed, and nearly positive that octave can find it, I added an environment variable to it just to be sure, so I don't think that's the error.  Is there something I can type into Octave to check though?
 
I tried nearly all of the other devices, especially the ones that don't need ghostscript, and still get the same error.
 
Here are my commands to make the movie:
 
call to avifile to make movie, create figure and handle: 
 
% open movie and prepare rendering window
mov = avifile(output_file,'compression','msmpeg4v2');
%open(mov);
hnd = figure;
set(hnd,'visible','off');
set(hnd,'WindowStyle','normal');
 
getframe/addframe:
 
 print (gcf,'tmp.fig','-dppm');%print (h, 'tmp.fig', '-dppm');
  ret = im2double (imread ('tmp.fig'));
  % Truncate to even size to accomodate addframe()
  if (mod (size (ret, 1), 2) > 0); ret = ret(2:end, :, :); endif
  if (mod (size (ret, 2), 2) > 0); ret = ret(:, 2:end, :); endif
      mov = addframe(mov,ret);
     %addframe(mov,gcf);
end
 
For the sake of completeness, I had mentioned earlier that  the getframe/addframe is in a larger loop (to overlay scatterplot data).  The entire larger loop for rendering is included below.
 
% do render
fprintf('rendering frames...\n');
for i = 1:subsamp:numel(dd)
    if (mod(i,100)==0)
        fprintf('frame %d/%d\n', i, numel(dd));
    end
 
    % read current image and trim its width and height to a multiple of 4
    img = imread([img_dir,'/',dd(i).name]);
    trim_x = mod(size(img,2),4);
    trim_y = mod(size(img,1),4);
    img = img(1:end-trim_y,1:end-trim_x);
 
    % display current image
    set(0,'CurrentFigure',hnd);
    imshow(img);
 
    % if there is scatterplot data for this frame, show it
    which_block = map(i);
    if (which_block > 0)
        % grab data chunk for this frame
        block = truth(starts(which_block):ends(which_block),:);
        pts = block(:,7:8);
        ids = block(:,2);
 
        % overlay scatterplot data
       hold on;
        scatter(pts(:,1),pts(:,2),30);
        hold off;
    end
    
    % add this frame to movie file
    %mov = addframe(mov,gcf);
%     renderer = get(hnd,'renderer');
%     if strcmp(renderer,'painters')
%         renderer = 'opengl';
%     end
%     set(hnd, 'Units', 'pixels');
%     pixelsperinch = get(0,'screenpixelsperInch');
%     frame = hardcopy(hnd, ['-d' renderer], ['-r' num2str(round(pixelsperinch))]);
  print (gcf,'tmp.fig','-dppm');%print (h, 'tmp.fig', '-dppm');
  ret = im2double (imread ('tmp.fig'));
  % Truncate to even size to accomodate addframe()
  if (mod (size (ret, 1), 2) > 0); ret = ret(2:end, :, :); endif
  if (mod (size (ret, 2), 2) > 0); ret = ret(:, 2:end, :); endif
      mov = addframe(mov,ret);
     %addframe(mov,gcf);
end
 
% close movie file
mov = close(mov);
fprintf('done!\n');
 
Thanks again Philip for your time.  I appreciate any other help you can give, but understand if you don't have the time.
 
 
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]