save high resolution figures with parfor in matlab - matlab

I am using parfor loop to produce and save quite big number of figures. Due to the amount of data which will be presented in the figures, the resolution of the figures need to be high, something around 920 dpi. Using the normal for, the function works fine. But when we switch to parfor the resolution of the produced and saved pictures becomes totally low.
This is the figure handle creation part:
mainFig=figure('visible','off');
set(mainFig, 'Renderer', 'OpenGL');
and here is the saving part code:
print(mainFig,'-djpeg','-r920',strcat(MyDir,measure,sec_suffix,'.jpeg'))
any idea?
Thanks

This is a documented limitation of printing in headless mode:
Printing and Exporting without a Display
On a UNIX platform (including Macintosh), where you can start in
MATLAB nodisplay mode (matlabĀ -nodisplay), you can print using
most of the drivers you can use with a display and export to most of
the same file formats. The PostScript and Ghostscript devices all
function in nodisplay mode on UNIX platforms. The graphic devices
-djpeg, -dpng, -dtiff (compressed TIFF bitmaps), and -tiff
(EPS with TIFF preview) work as well, but under nodisplay they use
Ghostscript to generate output instead of using the drivers built into
MATLAB. However, Ghostscript ignores the -r option when generating
-djpeg, -dpng, -dtiff, and -tiff image files. This means that
you cannot vary the resolution of image files when running in
nodisplay mode.
The same is true for the -noFigureWindows startup option which
suppresses figures on all platforms. On Windows platforms the -dwin,
-dwinc, and -dsetup options operate as usual under
-noFigureWindows. However, the printpreview GUI does not function
in this mode. Naturally, the Windows only -dwin and -dwinc output
formats cannot be used on UNIX or Mac platforms with or without a
display.
Resolution Considerations
Use -rnumber to specify the resolution of the generated output. In
general, using a higher value will yield higher quality output but at
the cost of larger output files. It affects the resolution and output
size of all MATLAB built-in raster formats (which are identified in
column four of the table in Graphics Format Files).
Note: Built-in graphics formats are generated directly from MATLAB without conversion through the Ghostscript library. Also, in headless
(nodisplay) mode, writing to certain image formats is not done by
built-in drivers, as it is when a display is being used. These formats
are -djpeg, -dtiff, and -dpng. Furthermore, the -dhdf and
-dbmp formats cannot be generated in headless mode (but you can
substitute -dbmp16m for -dbmp). See "Printing and Exporting
without a Display" for details on printing when not using a display.
Unlike the built-in MATLAB formats, graphic output generated via
Ghostscript does not directly obey -r option settings. However, the
intermediate PostScript file generated by MATLAB as input for the
Ghostscript processor is affected by the -r setting and thus can
indirectly influence the quality of the final Ghostscript generated
output.
The effect of the -r option on output quality can be subtle at
ordinary magnification when using the OpenGL or ZBuffer renderers and
writing to one of the MATLAB built-in raster formats, or when
generating vector output that contains an embedded raster image (for
example, PostScript or PDF). The effect of specifying higher
resolution is more apparent when viewing the output at higher
magnification or when printed, since a larger -r setting provides
more data to use when scaling the image.
When generating fully vectorized output (as when using the Painters
renderer to output a vector format such as PostScript or PDF), the
resolution setting affects the degree of detail of the output; setting
resolution higher generates crisper output (but small changes in the
resolution may have no observable effect). For example, the gap widths
of lines that do not use a solid ('-') linestyle can be affected.
parfor spawns headless MATLAB instances (both Windows and Unix), so according to the above, the worker processes will fallback to Ghostscript printing driver which ignores the -r option.
When you export figures to raster graphics format (PNG, JPEG, TIFF, etc..) there are two cases:
if you printing in a normal session, MATLAB will use its built-in drivers to generate the graphics files directly, and should obey the resolution you specify
on the other hand, if you printing in headless mode, MATLAB will internally export the figure in Postscript vector format, and then use Ghostscript to convert it to the requested raster format using the following Ghostscript options:
-dNOPAUSE -q
-I"C:\Program Files\MATLAB\R2014a\sys\extern\win64\ghostscript\ps_files"
-I"C:\Program Files\MATLAB\R2014a\sys\extern\win64\ghostscript\fonts"
-sDEVICE=jpeg
-g576x432
-sOutputFile="file.jpeg"
as you can see, for some reason MATLAB uses a fixed target size 576x432 in headless mode when converting the PS file to other formats.
Here is some code for quick experimentation. I've tested it on a local parallel pool; All of the raster formats (PNG, JPEG, TIFF, PPM) had a fixed size of 576x432 (-r option ignored as previously explained). The PDF was also generated by converting the PS file to PDF (using -sDEVICE=pdfwrite Ghostscript output device).
fmt = {'ppm', 'tiff', 'png', 'jpeg', 'epsc2', 'pdf'};
outfolder = 'C:\Users\Amro\Desktop\print_test';
parpool(4)
parfor i=1:4
fig = figure(i);
% a random plot
ax = axes('Parent',fig);
plot(ax, cumsum(rand(1000,1)-0.5))
% save in each specified format (-r option is mostly ignored)
for f=1:numel(fmt)
print(fig, ['-d' fmt{f}], '-r920', ...
fullfile(outfolder,sprintf('plot%d.%s',i,fmt{f})));
drawnow
end
% also save FIG-file
hgsave(fig, sprintf('plot%d.fig',i))
close(fig);
end
delete(gcp)
The way I see it, you ought to export as an EPS file, and manually convert it to whatever format you need. That way you get to specify the target image size in the Ghostscript command invoked (I wouldn't bother with the print -r resolution option, because it has little effect on vector formats)
The alternative would be to export FIG-files inside parfor. You would then load them in a normal MATLAB session with a display, and serially print with the desired resolution and format:
for i=1:4
fig = hgload('plotXX.fig');
movegui(fig, 'center')
print(fig, '-djpeg', '-r920', 'outXX.jpeg')
close(fig)
end

Related

Problem in .fig to .eps conversion (MATLABR 2015b)

I am generating a matlab figure with features
Separate background regions generated using patch command
A couple of arrows using arrow.m (https://www.mathworks.com/matlabcentral/fileexchange/278-arrow)
Annotations,Labels,etc
I have tried Matlab option to convert to .eps format as well as print2eps.m from https://www.mathworks.com/matlabcentral/fileexchange/23629-export_fig. In both cases I get following warning
Warning: Loading EPS file failed, so unable to perform post-processing. This is usually because the figure contains a large number of patch objects. Consider exporting to a bitmap format in this
case.
Following is the screenshot of two images. Left is Matlab, Right is in latex
As one can obverse, output file is not anywhere near to original matlab figure. Any thoughts on addressing this issue would be much appreciated

Matlab vision.VideoFileWriter output is too big

I'm using Computer Vision System Toolbox in Matlab (R2015a, Windows7) to mask frames in the video file and write them into a new video file. By masking, I replace about 80% of the image with 0s and 1s:
videoFileReader = vision.VideoFileReader(fin);
videoFileWriter=vision.VideoFileWriter(fout, ...
'FileFormat', 'MPEG4', 'FrameRate', videoFileReader.info.VideoFrameRate);
frame = step(videoFileReader);
frame_new=mask(frame); %user function
step(videoFileWriter, frame_new);
The size (1080 x 1920 x 3) and the format (single) of the original and modified frames remain the same. Yet the masked videos are much bigger than the original ones, e.g. 1GB original video turns into nearly 4GB after masking. These large new files can not be opened (Windows 7, VLC media). Handbrake does not recognize them as a legit video file either.
When I mask only about 20% of the image, the masked video still come out large (up to 2.5Gb), but I have no problem opening these.
I tried adding 'VideoCompressor', 'MJPEG Compressor', but this gives a warning.
videoFileWriter=vision.VideoFileWriter(fin, 'FileFormat', 'MPEG4', ...
'FrameRate', videoFileReader.info.VideoFrameRate, 'VideoCompressor', 'MJPEG Compressor');
<...>
Warning: The VideoCompressor property is not relevant in this configuration of the System object.
We have TBs of video data to deidentify, so any suggestion would be much appreciated.
Thanks!
Larissa,
The size of the output MPEG-4 file can be controlled by adjusting the Quality parameter of the system object. This is a value from 0-100 which controls the output bitrate. So, higher the quality, larger the file. The default value is 75. The system object uses the Microsft API's to create MPEG-4 files.
Secondly, you need to call release(videoFileWriter) to complete writing the file. I just want to confirm that you are doing it and have just omitted it for the purposes of this code snippet.
The VideoCompressor property is not valid for MPEG-4 file format because the compressor to be used is fixed. You can choose that property only when you write out AVI files. However, you probably will not reach the same level of compression as MPEG-4.
Hope this helps.
Dinesh
Download ffmpeg here:https://git.ffmpeg.org/ffmpeg.git
For windows, open a bash terminal and run:
cat <path to folder with images>/*.png | <path to ffmpeg bin folder>/ffmpeg.exe -f image2pipe -i - output.mkv
For unix, do similar but download the appropriate build of ffmpeg.
I tried on a 7.90GB folder and got a 6.4MB .mkv-file. Works like a charm!

How to freely draw lines and paths without any functionality in Simulink?

I would like to use Simulink to draw a signal path, without any functionality.
So, how do I disable all checks? Connect what ever I want, and name it with any names/symbols/characters? Is this possible?
In my opinion LibreOffice Draw or Microsoft Visio are not as nice for this purpose.
Simulink has all the blocks I need.
As already mentioned in the comments, Simulink is just not made for that. But you can use external applications like Inkscape (Open Source) or Adobe Illustrator (maybe MS Visio works as well) etc. All you need is a vector graphic of your Simulink Model.
You can get that for example by:
print -sMyModelname -dpdf -r300 model.pdf
or more generic:
modelname = 'myModel';
format = 'pdf'; %// or 'svg' or whatever
resolution = '300'; %// vector graphics do not really have a resolution,
%// but this way linewidth and canvas size are determined
filename = 'myModel.pdf';
print( ['-s' modelname], ['-d' format] , ['-r' resolution] , filename );
Now you easily can connect the blocks with splines as you wish and changed block annotations.
Apart from that: in a serious scientific context there is almost now way around Latex+Tikz.
Old post, still relevant.
Take for example Simscape or the older Power Systems toolbox.
They provide in/out ("physical") pins, allowing arbitrary connection of blocks, without classic Simulink checks if outputs are connected to outputs.
Without too much imagination, checks common in all "physical" toolboxes like
set_param(modelName, 'PhysicalModelingChecksum', '101269080');
are good for more than data integrity.
Someone else able to implement arbitrary connections, anyone?

Increase matlab figure resolution, when saving in headless mode

I have a plot, which I want to save with a bigger resolution. But the documentation states that Matlab ignores '-r' option to print command, when running in a headless mode. Is there some other way to increase printed figure resolution?
You could use the function export_fig written by Oliver Woodford. Its -r option (resolution) also works in headless mode. The function is available here.
As suggested above, export_fig provides a solution, but in later versions of Matlab, it may take a fair amount of tinkering to get it working.
export_fig(gcf, 'figure.png', '-png','-painters','-m2');
Should do the trick. The critical parameters here are:
'-painters' which forces matlab to use the correct rendering engine. The default (OpenGL) does not work in -nodisplay mode and "zbuffer" is no longer supported in recent version of matlab.
'-m2' which indicates output at x2 resolution. You can obviously specify '-m3' for x3 resolution and so on.

How can I read a text file of image intensity values and convert to a cv::Mat?

I am working on a project that requires reading intensity values of several images from a text file that has 3 lines of file header, followed by each image. Each image consists of 15 lines of header followed by the intensity values that are arranged in 48 rows, where each row has 144 tab-delimited pixel values.
I have already created a .mat file to read these into Matlab and create a structure array for each image. I'd like to use OpenCV to track features in the image sequence.
Would it make more sense to create a .cpp file that will read the text file or use OpenCV and Matlab mex files in order to accomplish my goal?
I'd recommend writing C++ code to read the file directly independent of Matlab. This way, you don't have to mess with row major vs. column major ordering and all that jazz. Also, are there specs for the image format? If it turns out to be a reasonably common format, you may be able to find an off-the-self reader/library for it.
If you want the visualization and/or other image processing capabilities of Matlab, then mex file might be a reasonable approach.