thehammadishaq commited on
Commit
c8dfd87
·
1 Parent(s): 3924835

DICOM Supported

Browse files
Files changed (2) hide show
  1. app.py +60 -5
  2. requirements.txt +2 -1
app.py CHANGED
@@ -17,6 +17,8 @@ import io
17
  import uuid
18
  from datetime import datetime, timedelta
19
  import base64
 
 
20
 
21
  # Configuration
22
  MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
@@ -118,7 +120,54 @@ def process_predictions(predictions):
118
  decoded.append([(class_names[i], float(pred[i])) for i in top_indices])
119
  return decoded
120
 
121
- def preprocess_image(file_bytes):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  img = cv2.imdecode(np.frombuffer(file_bytes, np.uint8), cv2.IMREAD_COLOR)
123
  img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
124
  return cv2.resize(img, (540, 540), interpolation=cv2.INTER_AREA)
@@ -129,15 +178,18 @@ async def analyze_image(
129
  request: Request,
130
  file: UploadFile = File(...)
131
  ):
132
- if not file.content_type.startswith('image/'):
133
- raise HTTPException(400, "Only image files accepted")
 
 
 
134
 
135
  if file.size > MAX_FILE_SIZE:
136
  raise HTTPException(413, f"File too large (max {MAX_FILE_SIZE//1024//1024}MB)")
137
 
138
  try:
139
  contents = await file.read()
140
- img = preprocess_image(contents)
141
 
142
  img_array = img_to_array(img)
143
  img_array = np.expand_dims(img_array, axis=0)
@@ -165,7 +217,10 @@ async def analyze_image(
165
  async def health_check():
166
  return {
167
  "status": "healthy",
168
- "timestamp": datetime.now().isoformat()
 
 
 
169
  }
170
 
171
  if __name__ == "__main__":
 
17
  import uuid
18
  from datetime import datetime, timedelta
19
  import base64
20
+ import pydicom
21
+ import os
22
 
23
  # Configuration
24
  MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
 
120
  decoded.append([(class_names[i], float(pred[i])) for i in top_indices])
121
  return decoded
122
 
123
+ def preprocess_dicom(file_bytes):
124
+ """Process DICOM format images for the model."""
125
+ # Save the bytes to a temporary file
126
+ temp_file = "temp_dicom.dcm"
127
+ with open(temp_file, "wb") as f:
128
+ f.write(file_bytes)
129
+
130
+ try:
131
+ # Read the DICOM file
132
+ dicom_data = pydicom.dcmread(temp_file)
133
+
134
+ # Convert DICOM pixel data to numpy array
135
+ img = dicom_data.pixel_array
136
+
137
+ # DICOM images are often 16-bit or higher, normalize to 8-bit for visualization
138
+ if img.dtype != np.uint8:
139
+ # Scale to [0, 255] for 8-bit representation
140
+ img = img.astype(np.float32)
141
+ img = (img - img.min()) / (img.max() - img.min()) * 255.0
142
+ img = img.astype(np.uint8)
143
+
144
+ # Check if grayscale and convert to RGB
145
+ if len(img.shape) == 2:
146
+ img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
147
+ elif len(img.shape) == 3 and img.shape[2] == 1:
148
+ img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
149
+
150
+ # Resize for model input
151
+ img = cv2.resize(img, (540, 540), interpolation=cv2.INTER_AREA)
152
+
153
+ return img
154
+ finally:
155
+ # Clean up temporary file
156
+ if os.path.exists(temp_file):
157
+ os.remove(temp_file)
158
+
159
+ def preprocess_image(file_bytes, content_type=None):
160
+ """Process images for the model, handling both DICOM and standard formats."""
161
+ # Check if the file is a DICOM file
162
+ if content_type and ('dicom' in content_type.lower() or content_type.lower() == 'application/octet-stream'):
163
+ try:
164
+ return preprocess_dicom(file_bytes)
165
+ except Exception as e:
166
+ print(f"DICOM processing error: {e}")
167
+ # Fall back to standard image processing if DICOM processing fails
168
+ pass
169
+
170
+ # Process as standard image format
171
  img = cv2.imdecode(np.frombuffer(file_bytes, np.uint8), cv2.IMREAD_COLOR)
172
  img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
173
  return cv2.resize(img, (540, 540), interpolation=cv2.INTER_AREA)
 
178
  request: Request,
179
  file: UploadFile = File(...)
180
  ):
181
+ # Accept both standard image formats and DICOM files
182
+ if not (file.content_type.startswith('image/') or
183
+ 'dicom' in file.content_type.lower() or
184
+ file.content_type == 'application/octet-stream'):
185
+ raise HTTPException(400, "Only image or DICOM files accepted")
186
 
187
  if file.size > MAX_FILE_SIZE:
188
  raise HTTPException(413, f"File too large (max {MAX_FILE_SIZE//1024//1024}MB)")
189
 
190
  try:
191
  contents = await file.read()
192
+ img = preprocess_image(contents, file.content_type)
193
 
194
  img_array = img_to_array(img)
195
  img_array = np.expand_dims(img_array, axis=0)
 
217
  async def health_check():
218
  return {
219
  "status": "healthy",
220
+ "timestamp": datetime.now().isoformat(),
221
+ "features": {
222
+ "dicom_support": True
223
+ }
224
  }
225
 
226
  if __name__ == "__main__":
requirements.txt CHANGED
@@ -7,4 +7,5 @@ matplotlib==3.7.1
7
  python-multipart==0.0.6
8
  uvicorn==0.22.0
9
  slowapi==0.1.8
10
- redis==4.5.5
 
 
7
  python-multipart==0.0.6
8
  uvicorn==0.22.0
9
  slowapi==0.1.8
10
+ redis==4.5.5
11
+ pydicom==3.0.1