3 votes

Les méthodes de redimensionnement d'images (resizeBilinear et resizeNearestNeighbor) dans Tensorflow.js ne renvoient pas les bons résultats.

Problème

  1. Quelle est la différence entre resizeBilinear(*1) et resizeNearestNeighbor(*2) ? En particulier, resizeNearestNeighbor ne renvoie pas l'image correcte (la moitié de l'image est noire). (La moitié de l'image est noire.)
  2. ResizeBilinear ne renvoie pas les bons résultats pour la segmentation. (La moitié de l'image est grise.) Comment cela se fait-il ? Ce résultat est très similaire à celui de resizeNearestNeighbor.

Contexte

Je veux développer une application qui fait de la segmentation dans Tensorflow.js. Heureusement, j'ai trouvé un exemple de code pour la segmentation en Python. (*3) Je pense pouvoir faire de la segmentation dans Tensorflow.js en convertissant le modèle Keras acquis ici en modèle TFJS. J'ai essayé de redimensionner les images dans Tensorflow.js mais je n'arrive pas à obtenir les bons résultats. Quelqu'un a-t-il une bonne idée ?

Code

Voici le code source que j'ai écrit. (Je n'ai pas l'habitude d'écrire du JavaScript.)

<!DOCTYPE html>
<html>
<head></head>
<meta charset="utf-8"/>
<body>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
<canvas id="canvas1" width="256" height="256" style="border: 2px solid;"></canvas>
<canvas id='canvas2' width="128" height="128" style="border: 2px solid;"></canvas>
<canvas id='canvas3' width="128" height="128" style="border: 2px solid;"></canvas>
<canvas id='canvas4' width="128" height="128" style="border: 2px solid;"></canvas>
<canvas id='canvas5' width="128" height="128" style="border: 2px solid;"></canvas>
<script>

var inputImg = new Image();inputImg.src = "../00_resources/woman172.jpg";
const canvas1 = document.getElementById('canvas1');
const canvas2 = document.getElementById('canvas2');
const canvas3 = document.getElementById('canvas3');
const canvas4 = document.getElementById('canvas4');
const canvas5 = document.getElementById('canvas5');

const SIZE = 128;
const COL_CHANNEL = 3;
const BIN_CHANNEL = 1;

inputImg.onload = () => {
  const inCtx = canvas1.getContext('2d');
  inCtx.drawImage(inputImg, 0, 0, canvas1.width, canvas1.height);
};

(async() => {

    // load model
    let model = await tf.loadGraphModel('/tfjsdoc/Portrait-Segmentation/model/deconv_bnoptimized_munet_to_tfjs_graph_model/model.json');

    // image1 (original image)
    let img1 = tf.browser.fromPixels(canvas1, COL_CHANNEL);
    tf.browser.toPixels(img1, canvas2);// OK

    // image2 (resized image - using 'resizeNearestNeighbor')
    let img2 = img1.resizeNearestNeighbor([SIZE, SIZE]).toFloat().div(tf.scalar(255));
    tf.browser.toPixels(img2, canvas3);// NG

    // image3 (resized image - using 'resizeBilinear')
    let img3 = img1.resizeBilinear([SIZE, SIZE]).toFloat().div(tf.scalar(255));
    tf.browser.toPixels(img3, canvas4);// OK?

    // predict (image3 is used to make predictions, but the same problem occurs as in image2)
    let pred = await model.predict(tf.reshape(img3, [-1,SIZE,SIZE,COL_CHANNEL])).data();
    tf.browser.toPixels(tf.tensor(pred, [SIZE,SIZE, BIN_CHANNEL]), canvas5);// NG

})();

</script>
</body>
</html>

Saisir le résultat de l'exécution

De gauche à droite.

  • image originale
  • L'image originale est prise et dessinée sur la toile
  • Image originale redimensionnée à l'aide de resizeNearestNeighbor et dessinée sur la toile (la moitié de l'image est noire)
  • Image originale redimensionnée à l'aide de resizeBilinear et dessinée sur la toile (à droite)
  • Segmentation de l'image originale redimensionnée à l'aide de resizeBilinear et dessinée sur le canevas (la moitié de l'image est grise)

Références

(*1) https://js.tensorflow.org/api/latest/#image.resizeBilinear

(*2) https://js.tensorflow.org/api/latest/#image.resizeNearestNeighbor

(*3) https://github.com/anilsathyan7/Portrait-Segmentation

1voto

ytrao Points 17

D'après mon expérience, il semble que les deux méthodes permettent un redimensionnement similaire de l'image d'entrée. ResizeBilinear effectue une interpolation bilinéaire sur l'image.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X