日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

微信小程序前端如何調用python后端的模型詳解_python

作者:慢慢來的小邵 ? 更新時間: 2022-06-19 編程語言

需求:

小程序端拍照調用python訓練好的圖片分類模型。實現圖片分類識別的功能。

微信小程序端:

重點在chooseImage函數中,根據圖片路徑獲取到圖片傳遞給flask的url;

Page({
    data: {
        SHOW_TOP: true,
        canRecordStart: false,
    },
    data: {
        tempFilePaths:'',
        sourceType: ['camera', 'album']
      },
    isSpeaking: false,
    accessToken: "",
    onLoad: function (options) {
        
        console.log("onLoad!");
        this.setHeader();
        var that=this
        wx.showShareMenu({
            withShareTicket: true //要求小程序返回分享目標信息
        });
        var isShowed = wx.getStorageSync("tip");
        if (isShowed != 1) {
            setTimeout(() => {
                this.setData({
                    SHOW_TOP: false
                })
                wx.setStorageSync("tip", 1)
            }, 3 * 1000)
        } else {
            this.setData({
                SHOW_TOP: false
            })
        };
    },
    },
    
 //頭像點擊處理事件,使用wx.showActionSheet()調用菜單欄
 buttonclick: function () {
    const that = this
    wx.showActionSheet({
      itemList: ['拍照', '相冊'],
      itemColor: '',
      //成功時回調
      success: function (res) {
        if (!res.cancel) {
          /*
           res.tapIndex返回用戶點擊的按鈕序號,從上到下的順序,從0開始
           比如用戶點擊本例中的拍照就返回0,相冊就返回1
           我們res.tapIndex的值傳給chooseImage()
          */
          that.chooseImage(res.tapIndex)
        }
      },
      
setHeader(){
    const tempFilePaths = wx.getStorageSync('tempFilePaths');
    if (tempFilePaths) {
      this.setData({
        tempFilePaths: tempFilePaths
      })
    } else {
      this.setData({
        tempFilePaths: '/images/camera.png'
      })
    }
  },

  chooseImage(tapIndex) {
    const checkeddata = true
    const that = this
    wx.chooseImage({
    //count表示一次可以選擇多少照片
      count: 1,
      //sizeType所選的圖片的尺寸,original原圖,compressed壓縮圖
      sizeType: ['original', 'compressed'],
      //如果sourceType為camera則調用攝像頭,為album時調用相冊
      sourceType: [that.data.sourceType[tapIndex]],
      success(res) {
        // tempFilePath可以作為img標簽的src屬性顯示圖片
        console.log(res);
        const tempFilePaths = res.tempFilePaths
        //將選擇到的圖片緩存到本地storage中
        wx.setStorageSync('tempFilePaths', tempFilePaths)
        /*
		由于在我們選擇圖片后圖片只是保存到storage中,所以我們需要調用一次   	        setHeader()方法來使頁面上的頭像更新
		*/
        that.setHeader();
        // wx.showToast({
        //   title: '設置成功',
        //   icon: 'none',
        // //   duration: 2000
        // })
        wx.showLoading({
            title: '識別中...',
        })
        
        var team_image = wx.getFileSystemManager().readFileSync(res.tempFilePaths[0], "base64")
        wx.request({
          url: 'http://127.0.0.1:5000/upload', //API地址,upload是我給路由起的名字,參照下面的python代碼
                     method: "POST",
          header: {
                     'content-type': "application/x-www-form-urlencoded",
                    },
          data: {image: team_image},//將數據傳給后端
     
        success: function (res) {
            console.log(res.data);  //控制臺輸出返回數據  
            wx.hideLoading()
            wx.showModal({

                title: '識別結果', 
                confirmText: "識別正確",
                cancelText:"識別錯誤",
                content: res.data, 
                success: function(res) { 
                if (res.confirm) {
                console.log('識別正確')
                } else if (res.cancel) {
                console.log('重新識別')
                }
                }
                })     
          }
        })
      }
    })
  },
});

flask端:

將圖片裁剪,填充,調用自己訓練保存最優的模型,用softmax處理結果矩陣,最后得到預測種類

# coding=utf-8
from flask import Flask, render_template, request, jsonify
from werkzeug.utils import secure_filename
from datetime import timedelta
from flask import Flask, render_template, request
import torchvision.transforms as transforms
from PIL import Image
from torchvision import models
import os
import torch
import json
import numpy as np
import torch.nn as nn
import matplotlib.pyplot as plt
import base64

app = Flask(__name__)

def softmax(x):
    exp_x = np.exp(x)
    softmax_x = exp_x / np.sum(exp_x, 0)
    return softmax_x

with open('dir_label.txt', 'r', encoding='utf-8') as f:
    labels = f.readlines()
    print("oldlabels:",labels)
    labels = list(map(lambda x: x.strip().split('\t'), labels))
    print("newlabels:",labels)

def padding_black(img):
    w, h = img.size

    scale = 224. / max(w, h)
    img_fg = img.resize([int(x) for x in [w * scale, h * scale]])

    size_fg = img_fg.size
    size_bg = 224

    img_bg = Image.new("RGB", (size_bg, size_bg))

    img_bg.paste(img_fg, ((size_bg - size_fg[0]) // 2,
                              (size_bg - size_fg[1]) // 2))

    img = img_bg
    return img
# 輸出
@app.route('/')
def hello_world():
    return 'Hello World!'

# 設置允許的文件格式
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'JPG', 'PNG', 'bmp'])
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

# 設置靜態文件緩存過期時間
app.send_file_max_age_default = timedelta(seconds=1)

# 添加路由
@app.route('/upload', methods=['POST', 'GET'])
def upload():
    if request.method == 'POST':
        # 通過file標簽獲取文件
        team_image = base64.b64decode(request.form.get("image"))  # 隊base64進行解碼還原。
        with open("static/111111.jpg", "wb") as f:
            f.write(team_image)
        image = Image.open("static/111111.jpg")
        # image = Image.open('laji.jpg')
        image = image.convert('RGB')
        image = padding_black(image)
        transform1 = transforms.Compose([
            transforms.Resize(224),
            transforms.ToTensor(),
        ])
        image = transform1(image)
        image = image.unsqueeze(0)
        # image = torch.unsqueeze(image, dim=0).float()
        print(image.shape)
        model = models.resnet50(pretrained=False)
        fc_inputs = model.fc.in_features
        model.fc = nn.Linear(fc_inputs, 214)
        # model = model.cuda()
        # 加載訓練好的模型
        checkpoint = torch.load('model_best_checkpoint_resnet50.pth.tar')
        model.load_state_dict(checkpoint['state_dict'])
        model.eval()

        src = image.numpy()
        src = src.reshape(3, 224, 224)
        src = np.transpose(src, (1, 2, 0))
        # image = image.cuda()
        # label = label.cuda()
        pred = model(image)
        pred = pred.data.cpu().numpy()[0]

        score = softmax(pred)
        pred_id = np.argmax(score)

        plt.imshow(src)
        print('預測結果:', labels[pred_id][0])
        # return labels[pred_id][0];
        return json.dumps(labels[pred_id][0], ensure_ascii=False)//將預測結果傳回給前端
        # plt.show()
    #     return render_template('upload_ok.html')
    #     重新返回上傳界面
    # return render_template('upload.html')

if __name__ == '__main__':
    app.run(debug=False)

大致的效果:

但是在手機上測試的話,wx.request{}里的url的域名不規范,不能出現這種端口號,目前還在想解決辦法,有知道的大佬還望告知。

總結

原文鏈接:https://blog.csdn.net/m0_44946030/article/details/115557881

欄目分類
最近更新