web-dev-qa-db-fra.com

Dans MATLAB, comment puis-je tracer une image et enregistrer le résultat sans l'afficher?

Cette question commence en quelque sorte par/ cette question se termine. MATLAB dispose d’un système d’affichage des images puissant et flexible qui vous permet d’utiliser les commandes imshow et plot pour afficher des images complexes, puis enregistrer le résultat. Par exemple:

im = imread('image.tif');
f = figure, imshow(im, 'Border', 'tight');
rectangle('Position', [100, 100, 10, 10]);
print(f, '-r80', '-dtiff', 'image2.tif');

Cela fonctionne très bien. 

Le problème est que si vous effectuez beaucoup de traitement d'image, il commence à être réel de faire glisser chaque image que vous créez - vous voulez surtout les enregistrer. Je sais que je pourrais directement écrire sur une image, puis sauvegarder le résultat. Mais utiliser plot/rectangle/imshow est si simple, j'espère donc qu'il existe une commande permettant d'appeler plot, imshow, etc., de ne pas afficher les résultats et de sauvegarder ensuite ce qui aurait été affiché. Quelqu'un sait-il des solutions rapides pour cela? 

Alternativement, un moyen rapide de mettre une spline sur un bitmap pourrait fonctionner ...

41
Joe Soul-bringer

Lorsque vous créez la figure, vous définissez la propriété Visibile sur Off .

f = figure('visible','off')

Ce qui dans votre cas serait

im = imread('image.tif');
f = figure('visible','off'), imshow(im, 'Border', 'tight');
rectangle('Position', [100, 100, 10, 10]);
print(f, '-r80', '-dtiff', 'image2.tif');

Et si vous voulez le revoir, vous pouvez le faire

set(f,'visible','on')
44
Bessi

La réponse simple à votre question est donnée par Bessi et M. Fooz : définissez le paramètre "Visible" du chiffre sur "off". Bien qu'il soit très facile d'utiliser des commandes telles que IMSHOW et PRINT pour générer des chiffres, je vais résumer pourquoi je pense que ce n'est pas nécessairement la meilleure option:

  • Comme l'illustre la réponse de M. Fooz, de nombreux autres facteurs entrent en jeu lorsqu'on tente de sauvegarder des chiffres sous forme d'images. Le type de sortie que vous obtiendrez dépendra de nombreux paramètres de chiffres et d'axes, augmentant ainsi la probabilité que vous n'obteniez pas la sortie souhaitée. Cela pourrait être particulièrement problématique si vous définissez vos figures comme étant invisibles, car vous ne remarquerez aucune anomalie pouvant être provoquée par une modification du paramètre par défaut de la figure ou des axes. En bref, votre sortie devient très sensible à un certain nombre de paramètres que vous devrez ensuite ajouter à votre code pour contrôler votre sortie, comme le montre l'exemple de M. Fooz.

  • Même si vous ne visualisez pas les figures telles qu'elles sont construites, vous faites probablement en sorte que MATLAB fasse plus de travail que nécessaire. Les objets graphiques sont toujours créés, même s'ils ne sont pas rendus. Si la vitesse est un problème, générer des images à partir de chiffres ne semble pas être la solution idéale.

Ma suggestion est de modifier les données d'image directement et de les enregistrer avec IMWRITE . Ce n'est peut-être pas aussi facile que d'utiliser IMSHOW et d'autres solutions de traçage, mais je pense que c'est plus efficace et donne des résultats plus robustes et cohérents qui ne sont pas aussi sensibles aux divers paramètres de tracé. Pour l'exemple que vous donnez, je pense que le code alternatif permettant de créer un rectangle noir ressemblerait à ceci:

im = imread('image.tif');
[r,c,d] = size(im);
x0 = 100;
y0 = 100;
w = 10;
h = 10;
x = [x0:x0+w x0*ones(1,h+1) x0:x0+w (x0+w)*ones(1,h+1)];
y = [y0*ones(1,w+1) y0:y0+h (y0+h)*ones(1,w+1) y0:y0+h];
index = sub2ind([r c],y,x);
im(index) = 0;
im(index+r*c) = 0;
im(index+2*r*c) = 0;
imwrite(im,'image2.tif');
20
gnovice

Voici une réponse complètement différente:

Si vous voulez un fichier image, pourquoi ne pas simplement sauvegarder l'image au lieu de la figure entière?

im = magic(10)
imwrite(im/max(im(:)),'magic.jpg')

Prouvez ensuite que cela a fonctionné.

imshow('magic.jpg')

Cela peut être fait pour l'indexé et le RVB également pour différents formats de sortie.

4
MatlabDoug

Je développe un peu la solution de Bessi ici. J'ai trouvé très utile de savoir comment faire en sorte que l'image occupe toute la figure et de pouvoir contrôler étroitement la taille de l'image de sortie.

% prevent the figure window from appearing at all
f = figure('visible','off'); 
% alternative way of hiding an existing figure
set(f, 'visible','off'); % can use the GCF function instead

% If you start getting odd error messages or blank images,
% add in a DRAWNOW call.  Sometimes it helps fix rendering
% bugs, especially in long-running scripts on Linux.
%drawnow; 

% optional: have the axes take up the whole figure
subplot('position', [0 0 1 1]); 

% show the image and rectangle
im = imread('peppers.png');
imshow(im, 'border','tight');
rectangle('Position', [100, 100, 10, 10]);

% Save the image, controlling exactly the output
% image size (in this case, making it equal to 
% the input's). 
[H,W,D] = size(im);
dpi = 100;
set(f, 'paperposition', [0 0 W/dpi H/dpi]);
set(f, 'papersize', [W/dpi H/dpi]);
print(f, sprintf('-r%d',dpi), '-dtiff', 'image2.tif');

Si vous souhaitez convertir la figure en matrice, tapez "help @ avifile/addframe", puis extrayez la sous-fonction appelée "getFrameForFigure". C'est une fonction fournie par Mathworks qui utilise des méthodes (actuellement) non documentées pour extraire des données de la figure.

4
Mr Fooz

Vous pouvez utiliser -noFigureWindows pour désactiver tous les chiffres.

0
Daniel