---
# System prepended metadata

title: 舌診資料

---

# 舌診資料
## model 使用說明
### 舌頭切割模型


```python=
from tensorflow.keras.utils import img_to_array, load_img, save_img
from keras.models import load_model
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image

#model路徑
model = load_model('/content/drive/My Drive/TongeImageDataset-master/store/tongue_segmentation.model')

#切割模型model回傳切割結果圖片(img)
def predict(file):
  img_rows, img_cols = 128, 128
  img = load_img(file, target_size=(img_rows, img_cols, 3))
  x_1 = img_to_array(img)
  x = np.expand_dims(x_1, axis=0)
  y = model.predict(x)
  y_overall = np.multiply(x_1, y).reshape(img_rows, img_cols, 3)
  img = Image.fromarray(np.uint8(y_overall), "RGB")
  return img 
    

#input圖片路徑
result = predict("/content/drive/My Drive/TongeImageDataset-master/test/12.bmp") 
```
### 舌診預測模型
```python=
# use_tongue_examination_cnn(需使用GPU)
import torch
import torch.nn as nn
import torchvision
import torch.utils.data as Data
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import os
from torchvision.datasets import ImageFolder
from torchvision.transforms import ToTensor
import cv2

classes = ['black', 'normal', 'white', 'yellow']
def get_default_device():
    """Pick GPU if available, else CPU"""
    if torch.cuda.is_available():
        return torch.device('cuda')
    else:
        return torch.device('cpu')
def to_device(data, device):
    """Move tensor(s) to chosen device"""
    if isinstance(data, (list,tuple)):
        return [to_device(x, device) for x in data]
    return data.to(device, non_blocking=True)
device = get_default_device()
device
class ImageClassificationBase(nn.Module):
    def training_step(self, batch):
        images, labels = batch 
        out = self(images)                  # Generate predictions
        loss = F.cross_entropy(out, labels) # Calculate loss
        return loss
    
    def validation_step(self, batch):
        images, labels = batch 
        out = self(images)                    # Generate predictions
        loss = F.cross_entropy(out, labels)   # Calculate loss
        acc = accuracy(out, labels)           # Calculate accuracy
        return {'val_loss': loss.detach(), 'val_acc': acc}
        
    def validation_epoch_end(self, outputs):
        batch_losses = [x['val_loss'] for x in outputs]
        epoch_loss = torch.stack(batch_losses).mean()   # Combine losses
        batch_accs = [x['val_acc'] for x in outputs]
        epoch_acc = torch.stack(batch_accs).mean()      # Combine accuracies
        return {'val_loss': epoch_loss.item(), 'val_acc': epoch_acc.item()}
    
    def epoch_end(self, epoch, result):
        print("Epoch [{}], train_loss: {:.4f}, val_loss: {:.4f}, val_acc: {:.4f}".format(
            epoch, result['train_loss'], result['val_loss'], result['val_acc']))
        
def accuracy(outputs, labels):
    _, preds = torch.max(outputs, dim=1)
    return torch.tensor(torch.sum(preds == labels).item() / len(preds))

class CnnModel(ImageClassificationBase):
    def __init__(self):
        super().__init__()
        self.network = nn.Sequential(
            nn.Conv2d(3, 32, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2), # output: 64 x 16 x 16

            nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2), # output: 128 x 8 x 8

            nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2), # output: 256 x 4 x 4

            nn.Flatten(), 
            nn.Linear(256*4*4, 1024),
            nn.ReLU(),
            nn.Linear(1024, 512),
            nn.ReLU(),
            nn.Linear(512, 10))
        
    def forward(self, xb):
        return self.network(xb)

def predict_image(img, model):
    # Convert to a batch of 1
    xb = to_device(img.unsqueeze(0), device)
    # Get predictions from model
    yb = model(xb)
    # Pick index with highest probability
    _, preds  = torch.max(yb, dim=1)
    # Retrieve the class label
    return classes[preds[0].item()]
# 圖片路徑(.png)
image = cv2.imread("/content/drive/My Drive/data/test/normal/normal_122.png")
re_img = cv2.resize(image, (32, 32), interpolation=cv2.INTER_AREA)
transform = transforms.Compose([
    transforms.ToTensor()
])
img_tensor = transform(re_img)
model2 = to_device(CnnModel(), device)
# torch load 為model路徑
model2.load_state_dict(torch.load('/content/drive/My Drive/data/model/cnn.pth'))
# print結果
print('Predicted:', predict_image(img_tensor, model2))
# 結果會有['black', 'normal', 'white', 'yellow']這四種
```
## 首頁的文字敘述：是要評估舌頭的什麼
使用AI模型檢測舌頭外觀，評估身體情況並給予說明
## 舌頭的範例圖片：
照片要確實含有您的舌頭部分，需要有充足的光源並且不要失焦，注意飯後間隔1小時以上，不要有食物碎屑殘留在舌頭表面，否則判讀不具任何意義。
請參考下方範例圖片來上傳舌頭照片，即可得到判讀結果。
![](https://i.imgur.com/MSPuBZS.png)
## 舌頭 model 預測出來的結果
1. normal:舌色正常，您擁有健康的舌頭請繼續保持下去
2. black:舌頭表面有黑色舌苔，可能是氣血不暢，可食用花茶、薄荷茶、清淡飲食，調理氣血。
3. white:舌頭表面有白色舌苔，可能有過度疲勞、腸胃虛弱代謝變差，需多休息
4. yellow:舌頭表面有黃色舌苔，可能是腸胃狀況差、睡眠不足、抽菸等引起，需改善生活習慣

## 輸出結果所對應的圖片
![](https://i.imgur.com/HhG8Jc5.png)
![](https://i.imgur.com/y5zc75B.png)
![](https://i.imgur.com/YY8bUKy.png)
![](https://i.imgur.com/qRtsgRO.png)
