LoginSignup
28
27

More than 1 year has passed since last update.

Djangoで画像処理アプリケーションを作った

Last updated at Posted at 2019-02-25

はじめに

  • djangoで画像処理アプリケーションを作成しました。
  • とりあえずそれらしく動いたので現状をメモ。

サンプルコード

環境

Python 3.6.7
django 2.1.2
OpenCv 4.0.0
PyTorch 1.0.0

グレースケールに変換するアプリ

主な構成

gray_app
│ manage.py
│ db.sqlite3
├ app1
│   │ models.py
│   │ forms.py
│   │ urls.py
│   │ views.py
│   └ templates
│         └ app1
│             └ index.html
├ media
│   │ documents
│   └ output  
└ myapp
    │ settings.py
    └ urls.py

主なコード

models.py
from django.db import models

class Document(models.Model):
    description = models.CharField(max_length=255, blank=True)
    photo = models.ImageField(upload_to='documents/', default='defo')
    uploaded_at = models.DateTimeField(auto_now_add=True)
    output = models.ImageField(default = 'output/output.jpg')

forms.py
from django import forms
from .models import Document

class DocumentForm(forms.ModelForm):
    class Meta:
        model = Document
        fields = ('description', 'photo',)
  • 一番下の関数を書き換えることによって様々な画像処理が可能です。
views.py
from django.http import HttpResponse
from django.shortcuts import render, redirect
from .forms import DocumentForm
from .models import Document
import cv2
from django.conf import settings

def index(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('index')
    else:
        form = DocumentForm()
        max_id = Document.objects.latest('id').id
        obj = Document.objects.get(id = max_id)
        input_path = settings.BASE_DIR + obj.photo.url
        output_path = settings.BASE_DIR + "/media/output/output.jpg"
        gray(input_path,output_path)

    return render(request, 'app1/index.html', {
        'form': form,
        'obj':obj,
    })


###########ここをカスタマイズ############

def gray(input_path,output_path):
    img = cv2.imread(input_path)
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    cv2.imwrite(output_path, img_gray)

######################################
index.html
<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Upload</title>
    </head>
    <body>

        <form method="post" enctype="multipart/form-data">
            {% csrf_token %}
            {{ form.as_p }}
            <button type="submit">Upload</button>
        </form>

        <td>{{ obj.description }}</td>
        <!--<td>{{ obj.gray_photo.url }}</td>-->
        <td><img src="{{ obj.output.url }}" width="100" height="100"/></td>
        <td>{{ obj.uploaded_at }}</td>
    </body>
</html>

画面イメージ

スクリーンショット 2019-02-26 1.50.20.png

超解像画像に変換するアプリ

主な構成

super_resolve_app
│ manage.py
│ db.sqlite3
├ app1
│   │ models.py
│   │ forms.py
│   │ urls.py
│   │ views.py *変更点
│   │ super_resolve.py *変更点
│   │ model.py *変更点
│   │ model_epoch_30.pth *変更点
│   └ templates
│         └ app1
│             └ index.html  
├ media
│   │ documents
│   └ output   
└ myapp
    │ settings.py
    └ urls.py

主なコード

超解像の部分は、以下を参考にしました。
https://github.com/pytorch/examples/tree/master/super_resolution

views.py
from __future__ import print_function
from django.http import HttpResponse
from django.shortcuts import render, redirect
from .forms import DocumentForm
from .models import Document
import cv2
from django.conf import settings
import torch
from PIL import Image
from torchvision.transforms import ToTensor
import numpy as np
from .super_resolve import super_resolve


def index(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('index')
    else:
        form = DocumentForm()
        max_id = Document.objects.latest('id').id
        obj = Document.objects.get(id = max_id)

        input = settings.BASE_DIR + obj.photo.url
        output = settings.BASE_DIR + "/media/output/output.jpg"
        super_resolve(input, output)

    return render(request, 'app1/index.html', {
        'form': form,
        'obj':obj,
    })
super_resolve.py
import torch
from PIL import Image
from torchvision.transforms import ToTensor
import numpy as np
from django.conf import settings
from .model import Net


def super_resolve(input_url, output_url):
    # Training settings

    input_image = input_url

    img = Image.open(input_image).convert('YCbCr')
    y, cb, cr = img.split()

    model_path = settings.BASE_DIR + '/app1/model_epoch_30.pth'

    the_model = Net(3)
    the_model.load_state_dict(torch.load(model_path))

    img_to_tensor = ToTensor()
    input = img_to_tensor(y).view(1, -1, y.size[1], y.size[0])

    out = the_model(input)
    out = out.cpu()
    out_img_y = out[0].detach().numpy()
    out_img_y *= 255.0
    out_img_y = out_img_y.clip(0, 255)
    out_img_y = Image.fromarray(np.uint8(out_img_y[0]), mode='L')

    out_img_cb = cb.resize(out_img_y.size, Image.BICUBIC)
    out_img_cr = cr.resize(out_img_y.size, Image.BICUBIC)
    out_img = Image.merge('YCbCr', [out_img_y, out_img_cb, out_img_cr]).convert('RGB')

    out_img.save(output_url)
    print('output image saved to ', output_url)

画面イメージ

スクリーンショット 2019-02-26 1.49.19.png

実行方法

python manage.py makemigrations
python manage.py migrate
python manage.py runserver (IPアドレス:ポート番号)

注意事項

IPアドレスを指定する場合

settings.py
ALLOWED_HOSTS = ['IPアドレス']

参考記事

https://ymgsapo.com/show-image-imagefield/
https://ymgsapo.com/gray-scale-app/
https://qiita.com/hiroyuki_mrp/items/8b2b78e066f35edbfbfd

28
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
27