shiue20 commited on
Commit
01f123f
·
verified ·
1 Parent(s): 4294f08

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -20
app.py CHANGED
@@ -1,7 +1,7 @@
1
- from flask import Flask, request, jsonify, render_template, send_file, flash, redirect, url_for
2
  import os
3
  import cv2
4
  import numpy as np
 
5
  from werkzeug.utils import secure_filename
6
 
7
  app = Flask(__name__)
@@ -16,45 +16,51 @@ os.makedirs(RESULT_FOLDER, exist_ok=True)
16
 
17
  app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
18
  app.config['RESULT_FOLDER'] = RESULT_FOLDER
19
- app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
 
20
 
21
  def allowed_file(filename):
22
  return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
23
 
 
24
  def enhance_image(img, gamma=1.0, denoise='none', stylize=False):
25
  # Gamma correction
26
- invGamma = 1.0 / gamma
27
  table = np.array([((i / 255.0) ** invGamma) * 255 for i in np.arange(256)]).astype("uint8")
28
  img = cv2.LUT(img, table)
29
 
30
- # Enhance contrast (existing CLAHE)
31
  lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
32
  l, a, b = cv2.split(lab)
33
- clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
34
  cl = clahe.apply(l)
35
  img = cv2.merge((cl, a, b))
36
  img = cv2.cvtColor(img, cv2.COLOR_LAB2BGR)
37
 
38
- # Denoise
39
  if denoise == 'nonlocal':
40
- img = cv2.fastNlMeansDenoisingColored(img,None,10,10,7,21)
41
  elif denoise == 'median':
42
  img = cv2.medianBlur(img, 3)
43
 
44
- # Stylize (cartoon effect)
45
  if stylize:
46
- img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
47
- img_blur = cv2.medianBlur(img_gray, 7)
48
- edges = cv2.adaptiveThreshold(img_blur,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 2)
 
 
 
49
  color = cv2.bilateralFilter(img, 9, 250, 250)
50
  img = cv2.bitwise_and(color, color, mask=edges)
51
 
52
  return img
53
 
 
54
  def generate_damage_mask(img, threshold=500):
55
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
56
- tophat_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (17,17))
57
- tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, tophat_kernel)
58
 
59
  grad_x = cv2.Sobel(gray, cv2.CV_16S, 1, 0)
60
  grad_y = cv2.Sobel(gray, cv2.CV_16S, 0, 1)
@@ -65,19 +71,22 @@ def generate_damage_mask(img, threshold=500):
65
  combined = cv2.addWeighted(tophat, 1.0, gradient, 1.0, 0)
66
  _, mask = cv2.threshold(combined, threshold, 255, cv2.THRESH_BINARY)
67
  mask = cv2.medianBlur(mask, 5)
68
- mask = cv2.dilate(mask, np.ones((5,5), np.uint8), iterations=1)
69
 
70
  return mask
71
 
 
72
  def inpaint_damage(img, threshold):
73
  mask = generate_damage_mask(img, threshold)
74
  repaired = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)
75
  return repaired, mask
76
 
 
77
  @app.route('/', methods=['GET'])
78
  def index():
79
  return render_template('index.html')
80
 
 
81
  @app.route('/upload', methods=['POST'])
82
  def upload():
83
  if 'file' not in request.files:
@@ -96,7 +105,7 @@ def upload():
96
  if img is None:
97
  return jsonify(error='Invalid image file'), 400
98
 
99
- # Initial parameters, defaults
100
  threshold = 500
101
  gamma = 1.0
102
  denoise = 'none'
@@ -114,13 +123,15 @@ def upload():
114
  cv2.imwrite(mask_path, mask)
115
 
116
  return jsonify(
117
- original_image = url_for('uploaded_file', filename=filename),
118
- repaired_image = url_for('result_file', filename=repaired_filename),
119
- mask_image = url_for('result_file', filename=mask_filename)
120
  )
 
121
  else:
122
  return jsonify(error='Allowed image types are png, jpg, jpeg'), 400
123
 
 
124
  @app.route('/process', methods=['POST'])
125
  def process():
126
  data = request.get_json()
@@ -150,14 +161,16 @@ def process():
150
  cv2.imwrite(mask_path, mask)
151
 
152
  return jsonify(
153
- repaired_image = url_for('result_file', filename=repaired_filename),
154
- mask_image = url_for('result_file', filename=mask_filename)
155
  )
156
 
 
157
  @app.route('/uploads/<filename>')
158
  def uploaded_file(filename):
159
  return send_file(os.path.join(app.config['UPLOAD_FOLDER'], filename))
160
 
 
161
  @app.route('/results/<filename>')
162
  def result_file(filename):
163
  return send_file(os.path.join(app.config['RESULT_FOLDER'], filename))
 
 
1
  import os
2
  import cv2
3
  import numpy as np
4
+ from flask import Flask, request, jsonify, render_template, send_file, url_for
5
  from werkzeug.utils import secure_filename
6
 
7
  app = Flask(__name__)
 
16
 
17
  app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
18
  app.config['RESULT_FOLDER'] = RESULT_FOLDER
19
+ app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16 MB max
20
+
21
 
22
  def allowed_file(filename):
23
  return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
24
 
25
+
26
  def enhance_image(img, gamma=1.0, denoise='none', stylize=False):
27
  # Gamma correction
28
+ invGamma = 1.0 / gamma if gamma > 0 else 1.0
29
  table = np.array([((i / 255.0) ** invGamma) * 255 for i in np.arange(256)]).astype("uint8")
30
  img = cv2.LUT(img, table)
31
 
32
+ # CLAHE for contrast
33
  lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
34
  l, a, b = cv2.split(lab)
35
+ clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
36
  cl = clahe.apply(l)
37
  img = cv2.merge((cl, a, b))
38
  img = cv2.cvtColor(img, cv2.COLOR_LAB2BGR)
39
 
40
+ # Denoise options
41
  if denoise == 'nonlocal':
42
+ img = cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 21)
43
  elif denoise == 'median':
44
  img = cv2.medianBlur(img, 3)
45
 
46
+ # Stylize option (cartoon/sketch effect)
47
  if stylize:
48
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
49
+ blur = cv2.medianBlur(gray, 7)
50
+ edges = cv2.adaptiveThreshold(blur, 255,
51
+ cv2.ADAPTIVE_THRESH_MEAN_C,
52
+ cv2.THRESH_BINARY,
53
+ 9, 2)
54
  color = cv2.bilateralFilter(img, 9, 250, 250)
55
  img = cv2.bitwise_and(color, color, mask=edges)
56
 
57
  return img
58
 
59
+
60
  def generate_damage_mask(img, threshold=500):
61
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
62
+ kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (17, 17))
63
+ tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, kernel)
64
 
65
  grad_x = cv2.Sobel(gray, cv2.CV_16S, 1, 0)
66
  grad_y = cv2.Sobel(gray, cv2.CV_16S, 0, 1)
 
71
  combined = cv2.addWeighted(tophat, 1.0, gradient, 1.0, 0)
72
  _, mask = cv2.threshold(combined, threshold, 255, cv2.THRESH_BINARY)
73
  mask = cv2.medianBlur(mask, 5)
74
+ mask = cv2.dilate(mask, np.ones((5, 5), np.uint8), iterations=1)
75
 
76
  return mask
77
 
78
+
79
  def inpaint_damage(img, threshold):
80
  mask = generate_damage_mask(img, threshold)
81
  repaired = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)
82
  return repaired, mask
83
 
84
+
85
  @app.route('/', methods=['GET'])
86
  def index():
87
  return render_template('index.html')
88
 
89
+
90
  @app.route('/upload', methods=['POST'])
91
  def upload():
92
  if 'file' not in request.files:
 
105
  if img is None:
106
  return jsonify(error='Invalid image file'), 400
107
 
108
+ # Default parameters for first process
109
  threshold = 500
110
  gamma = 1.0
111
  denoise = 'none'
 
123
  cv2.imwrite(mask_path, mask)
124
 
125
  return jsonify(
126
+ original_image=url_for('uploaded_file', filename=filename),
127
+ repaired_image=url_for('result_file', filename=repaired_filename),
128
+ mask_image=url_for('result_file', filename=mask_filename)
129
  )
130
+
131
  else:
132
  return jsonify(error='Allowed image types are png, jpg, jpeg'), 400
133
 
134
+
135
  @app.route('/process', methods=['POST'])
136
  def process():
137
  data = request.get_json()
 
161
  cv2.imwrite(mask_path, mask)
162
 
163
  return jsonify(
164
+ repaired_image=url_for('result_file', filename=repaired_filename),
165
+ mask_image=url_for('result_file', filename=mask_filename)
166
  )
167
 
168
+
169
  @app.route('/uploads/<filename>')
170
  def uploaded_file(filename):
171
  return send_file(os.path.join(app.config['UPLOAD_FOLDER'], filename))
172
 
173
+
174
  @app.route('/results/<filename>')
175
  def result_file(filename):
176
  return send_file(os.path.join(app.config['RESULT_FOLDER'], filename))