Je crée une application flask qui permet aux utilisateurs de dessiner une lettre sur la toile et d'envoyer une image au backend en utilisant AJAX. Les images sont converties en niveaux de gris et inversées à l'aide de Pillow avant de passer par un CNN. Après avoir converti l'image en niveaux de gris, l'image est entièrement noire.

//this is the JavaScript code for sending canvas drawing to backend
function sendData() {
        $('#result').hide();
        $('#loadingImage').show()
        var scratchCanvas = document.getElementById('can');
        var context = scratchCanvas.getContext('2d');
        var dataURL = scratchCanvas.toDataURL("image/png");

        $.ajax({
            type: "POST",
            url: "/imgToText",
            data: {
                imageBase64: dataURL
            }
        }).done(function (data) {
            document.getElementById("result").innerHTML = "This is letter: " + data
            $('#loadingImage').hide();
            $('#result').show();
        });
    }

def prepare_image(image, target):
    '''
    Preprocess the image and prepare it for classification
    '''
    img_array = Image.open(BytesIO(image))
    img_array.show()
    img_array.save("normalPicture.png")
    bw = img_array.convert('L');

    bw.show()
    bw.save("allblack.png")
    img_array = ImageOps.invert(img_array)

    new_array = img_array.resize((target,target))

    img = img_to_array(new_array)
    img = img/255.0
    img = np.expand_dims(img, axis=0)
    return img


@app.route('/imgToText', methods=['POST'])
def imgToText():
    '''
    Image is received as DataURI, it is convereted to Image, and preprocessed.
    The model uses the preprocessed image to make a prediction. 

    returns JSON representation of the model prediction

    '''
    image_b64 = request.values['imageBase64']
    image_data = re.sub('^data:image/.+;base64,', '', image_b64)
    image_data =base64.b64decode(image_data)
    IMG_SIZE =28
    img = prepare_image(image_data, IMG_SIZE)

    #load model
    #model = load_model('model.h5')
    #get class names 
    y_Labels = {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F', 6: 'G', 7: 'H', 8: 'I', 9: 'J', 10: 'K', 11: 'L', 12: 'M', 13: 'N', 14: 'O', 15: 'P', 16: 'Q', 17: 'R', 18: 'S', 19: 'T', 20: 'U', 21: 'V', 22: 'W', 23: 'X', 24: 'Y', 25: 'Z', 26: 'a', 27: 'b', 28: 'd', 29: 'e', 30: 'f', 31: 'g', 32: 'h', 33: 'n', 34: 'q', 35: 'r', 36: 't'}
    #make prediction
    prediction =model.predict_classes(img)
    return jsonify(y_Labels[prediction[0]])

C'est le résultat de img_array.show():

enter image description here

Cette image est correcte.

Voici le résultat de bw.show() après sa conversion en niveaux de gris:

enter image description here

Pourquoi l'image est-elle entièrement noire après l'avoir convertie en niveaux de gris?

0
Suji 26 oct. 2020 à 06:53

2 réponses

Meilleure réponse

J'ai eu ce problème car img_array a un arrière-plan transparent. Pour résoudre ce problème, j'ai rempli l'arrière-plan de la toile d'une couleur.

Voici ma toile:

    canvas = document.getElementById('can');
    ctx = canvas.getContext("2d");
    w = canvas.width;
    h = canvas.height;
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, w, h);
    $('#can').mousedown(function (e) {
        mousePressed = true;
        Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, false);
    });

    $('#can').mousemove(function (e) {
        if (mousePressed) {
            Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true);
        }
    });

    $('#can').mouseup(function (e) {
        mousePressed = false;
    });
    $('#can').mouseleave(function (e) {
        mousePressed = false;
    });
    }
0
Suji 29 oct. 2020 à 12:45

Je pense que PIL s'attend à ce que les valeurs d'intensité des pixels soient comprises entre 0 et 255.

Et votre image a des valeurs comprises entre 0 et 1.

1
Myccha 26 oct. 2020 à 03:57