import os import cv2 import torch from flask import Flask, request, jsonify, send_file from basicsr.archs.srvgg_arch import SRVGGNetCompact from gfpgan.utils import GFPGANer from realesrgan.utils import RealESRGANer import uuid import tempfile # ウェイトファイルをダウンロード(存在しない場合) if not os.path.exists('realesr-general-x4v3.pth'): os.system("wget https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth -P .") if not os.path.exists('GFPGANv1.2.pth'): os.system("wget https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.2.pth -P .") if not os.path.exists('GFPGANv1.3.pth'): os.system("wget https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth -P .") if not os.path.exists('GFPGANv1.4.pth'): os.system("wget https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.4.pth -P .") if not os.path.exists('RestoreFormer.pth'): os.system("wget https://github.com/TencentARC/GFPGAN/releases/download/v1.3.4/RestoreFormer.pth -P .") if not os.path.exists('CodeFormer.pth'): os.system("wget https://github.com/TencentARC/GFPGAN/releases/download/v1.3.4/CodeFormer.pth -P .") app = Flask(__name__) # モデルの初期化 model = SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=32, upscale=4, act_type='prelu') model_path = 'realesr-general-x4v3.pth' half = True if torch.cuda.is_available() else False upsampler = RealESRGANer(scale=4, model_path=model_path, model=model, tile=0, tile_pad=10, pre_pad=0, half=half) os.makedirs('output', exist_ok=True) @app.route('/api/restore', methods=['POST']) def restore_image(): try: # リクエストからパラメータを取得 if 'file' not in request.files: return jsonify({'error': 'No file uploaded'}), 400 file = request.files['file'] version = request.form.get('version', 'v1.4') scale = float(request.form.get('scale', 2)) # weight = float(request.form.get('weight', 50)) / 100 # CodeFormer用のweightパラメータが必要な場合 # 一時ファイルに保存 temp_dir = tempfile.mkdtemp() input_path = os.path.join(temp_dir, file.filename) file.save(input_path) # 画像処理 extension = os.path.splitext(os.path.basename(str(input_path)))[1] img = cv2.imread(input_path, cv2.IMREAD_UNCHANGED) if len(img.shape) == 3 and img.shape[2] == 4: img_mode = 'RGBA' elif len(img.shape) == 2: img_mode = None img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) else: img_mode = None h, w = img.shape[0:2] if h < 300: img = cv2.resize(img, (w * 2, h * 2), interpolation=cv2.INTER_LANCZOS4) # バージョンに応じてモデルを選択 if version == 'v1.2': face_enhancer = GFPGANer( model_path='GFPGANv1.2.pth', upscale=2, arch='clean', channel_multiplier=2, bg_upsampler=upsampler) elif version == 'v1.3': face_enhancer = GFPGANer( model_path='GFPGANv1.3.pth', upscale=2, arch='clean', channel_multiplier=2, bg_upsampler=upsampler) elif version == 'v1.4': face_enhancer = GFPGANer( model_path='GFPGANv1.4.pth', upscale=2, arch='clean', channel_multiplier=2, bg_upsampler=upsampler) elif version == 'RestoreFormer': face_enhancer = GFPGANer( model_path='RestoreFormer.pth', upscale=2, arch='RestoreFormer', channel_multiplier=2, bg_upsampler=upsampler) elif version == 'CodeFormer': face_enhancer = GFPGANer( model_path='CodeFormer.pth', upscale=2, arch='CodeFormer', channel_multiplier=2, bg_upsampler=upsampler) elif version == 'RealESR-General-x4v3': face_enhancer = GFPGANer( model_path='realesr-general-x4v3.pth', upscale=2, arch='realesr-general', channel_multiplier=2, bg_upsampler=upsampler) # 画像を拡張 _, _, output = face_enhancer.enhance(img, has_aligned=False, only_center_face=False, paste_back=True) # スケール調整 if scale != 2: interpolation = cv2.INTER_AREA if scale < 2 else cv2.INTER_LANCZOS4 h, w = img.shape[0:2] output = cv2.resize(output, (int(w * scale / 2), int(h * scale / 2)), interpolation=interpolation) # 出力ファイルを保存 output_filename = f'output_{uuid.uuid4().hex}' if img_mode == 'RGBA': output_path = os.path.join('output', f'{output_filename}.png') cv2.imwrite(output_path, output) mimetype = 'image/png' else: output_path = os.path.join('output', f'{output_filename}.jpg') cv2.imwrite(output_path, output) mimetype = 'image/jpeg' # 結果を返す return send_file(output_path, mimetype=mimetype, as_attachment=True, download_name=os.path.basename(output_path)) except Exception as e: return jsonify({'error': str(e)}), 500 @app.route('/') def index(): return """ Image Upscaling & Restoration API

Image Upscaling & Restoration API

Result:

API Usage:

// JavaScript fetch code will appear here
""" if __name__ == '__main__': app.run(host='0.0.0.0', port=7860, debug=True)