Skier8402 commited on
Commit
95c04af
·
verified ·
1 Parent(s): 3e5dac2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -213
app.py CHANGED
@@ -1,3 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  from PIL import Image, ImageEnhance
3
  import pandas as pd
@@ -6,187 +36,50 @@ import io
6
  import os
7
  import tempfile
8
  import zipfile
9
- import cv2
10
-
11
- @st.cache_data
12
- def zoom_at_cv(img, x, y, zoom):
13
- """
14
- Zoom into an image at a specific location using OpenCV.
15
-
16
- Parameters:
17
- ----------
18
- img : PIL.Image
19
- Input image.
20
- x : float
21
- X-coordinate of the zoom center.
22
- y : float
23
- Y-coordinate of the zoom center.
24
- zoom : float
25
- Zoom factor.
26
-
27
- Returns:
28
- -------
29
- PIL.Image
30
- Zoomed image resized to 500x500 pixels.
31
- """
32
- # Convert PIL Image to OpenCV format
33
- img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
34
- h, w = img_cv.shape[:2]
35
-
36
- # Calculate the region to crop
37
- zoom_factor = zoom / 2
38
- left = max(int(x - w * zoom_factor), 0)
39
- top = max(int(y - h * zoom_factor), 0)
40
- right = min(int(x + w * zoom_factor), w)
41
- bottom = min(int(y + h * zoom_factor), h)
42
-
43
- # Crop and resize
44
- cropped = img_cv[top:bottom, left:right]
45
- resized = cv2.resize(cropped, (500, 500), interpolation=cv2.INTER_LANCZOS4)
46
-
47
- # Convert back to PIL format
48
- pil_img = Image.fromarray(cv2.cvtColor(resized, cv2.COLOR_BGR2RGB))
49
- return pil_img
50
-
51
- @st.cache_data
52
- def apply_enhancements_cv(img, x, y, zoom, contrast, brightness, sharpness):
53
- """
54
- Apply zoom and image enhancements using OpenCV.
55
-
56
- Parameters:
57
- ----------
58
- img : PIL.Image
59
- Input image.
60
- x : float
61
- X-coordinate of the zoom center.
62
- y : float
63
- Y-coordinate of the zoom center.
64
- zoom : float
65
- Zoom factor.
66
- contrast : float
67
- Contrast adjustment factor.
68
- brightness : float
69
- Brightness adjustment factor.
70
- sharpness : float
71
- Sharpness adjustment factor.
72
-
73
- Returns:
74
- -------
75
- PIL.Image
76
- Enhanced image resized to 500x500 pixels.
77
- """
78
- # Zoom the image
79
- zoomed = zoom_at_cv(img, x, y, zoom)
80
-
81
- # Apply image enhancements using PIL
82
- enhanced_contrast = ImageEnhance.Contrast(zoomed).enhance(contrast)
83
- enhanced_brightness = ImageEnhance.Brightness(enhanced_contrast).enhance(brightness)
84
- enhanced_sharpness = ImageEnhance.Sharpness(enhanced_brightness).enhance(sharpness)
85
-
86
- return enhanced_sharpness
87
-
88
- def create_zip(processed_img, description, params):
89
- """
90
- Create a zip archive containing the processed image and annotations.
91
-
92
- Parameters:
93
- ----------
94
- processed_img : PIL.Image
95
- The processed image.
96
- description : str
97
- Description of the image.
98
- params : dict
99
- Image parameters.
100
-
101
- Returns:
102
- -------
103
- bytes
104
- Byte content of the zip file.
105
- """
106
- with tempfile.TemporaryDirectory() as tmpdirname:
107
- img_path = os.path.join(tmpdirname, "processed_image.jpg")
108
- desc_path = os.path.join(tmpdirname, "description.txt")
109
- params_path = os.path.join(tmpdirname, "parameters.json")
110
-
111
- # Save processed image
112
- processed_img.save(img_path)
113
-
114
- # Save description
115
- with open(desc_path, "w") as f:
116
- f.write(description)
117
-
118
- # Save parameters
119
- pd.DataFrame([params]).to_json(params_path, orient="records")
120
-
121
- # Create zip
122
- zip_buffer = io.BytesIO()
123
- with zipfile.ZipFile(zip_buffer, "w") as zipf:
124
- zipf.write(img_path, arcname="processed_image.jpg")
125
- zipf.write(desc_path, arcname="description.txt")
126
- zipf.write(params_path, arcname="parameters.json")
127
 
128
- zip_buffer.seek(0)
129
- return zip_buffer
 
 
 
 
130
 
131
- # Streamlit App Configuration
132
- st.set_page_config(page_title="CLL Explorer", layout="wide")
133
- st.title("CLL Explorer: Cell Image Analysis Prep Tool")
134
 
135
- st.markdown("""
136
- ### About This Application
137
- This tool assists researchers in analyzing microscope images of any cell type.
138
- - **Upload** microscope images.
139
- - **Adjust** image view with zoom and enhancement controls.
140
- - **Detect** and measure cells automatically.
141
- - **Save** analysis results and annotations.
142
- """)
143
-
144
- uploaded_files = st.file_uploader("Upload Images", accept_multiple_files=True, type=["jpg", "png"])
145
 
146
  if uploaded_files:
147
- img_index = st.selectbox(
148
- "Select Image",
149
- range(len(uploaded_files)),
150
- format_func=lambda x: uploaded_files[x].name
151
- )
152
- img_data = uploaded_files[img_index].read()
153
- img = Image.open(io.BytesIO(img_data)).convert("RGB").resize((500, 500))
 
154
 
155
- # Create columns with image on the left and controls on the right
156
- image_col, controls_col = st.columns([3, 1])
157
-
158
- with image_col:
159
- st.subheader("Processed Image")
160
- if 'processed_img' in st.session_state:
161
- st.image(st.session_state.processed_img, use_column_width=True, caption="Processed Image")
162
- else:
163
- st.image(img, use_column_width=True, caption="Processed Image")
164
-
165
- with controls_col:
166
- st.subheader("Image Controls")
167
- x = st.slider("X Coordinate", 0.0, 500.0, 250.0, step=1.0)
168
- y = st.slider("Y Coordinate", 0.0, 500.0, 250.0, step=1.0)
169
- zoom = st.slider("Zoom", 1.0, 10.0, 5.0, step=0.1)
170
-
171
- with st.expander("Enhancement Settings", expanded=True):
172
- contrast = st.slider("Contrast", 0.0, 5.0, 1.0, step=0.1)
173
- brightness = st.slider("Brightness", 0.0, 5.0, 1.0, step=0.1)
174
- sharpness = st.slider("Sharpness", 0.0, 2.0, 1.0, step=0.1)
175
 
176
- if st.button("Apply Adjustments"):
177
- processed_img = apply_enhancements_cv(img, x, y, zoom, contrast, brightness, sharpness)
178
- st.session_state.processed_img = processed_img
179
 
180
- # Display Original Image Below
181
- st.subheader("Original Image")
182
- st.image(img, use_column_width=True, caption="Original Image")
183
 
184
- # Save and Export Options
185
- st.markdown("---")
186
- st.subheader("Save and Export Options")
 
 
 
187
 
188
- with st.expander("Add Annotations", expanded=True):
189
- description = st.text_area("Describe the image", "")
190
  params = {
191
  "coordinates_x": x,
192
  "coordinates_y": y,
@@ -195,47 +88,24 @@ if uploaded_files:
195
  "brightness": brightness,
196
  "sharpness": sharpness
197
  }
 
 
 
 
198
 
199
- if st.button("Prepare Download"):
200
- if 'processed_img' in st.session_state and description:
201
- zip_buffer = create_zip(st.session_state.processed_img, description, params)
202
- st.download_button(
203
- label="Download Zip",
204
- data=zip_buffer,
205
- file_name="processed_image_and_annotations.zip",
206
- mime="application/zip"
207
- )
208
- st.success("Zip file is ready for download.")
209
- else:
210
- st.warning("Ensure that the processed image is available and description is provided.")
211
-
212
- # Optional: Save Processed Image Locally
213
- save_image = st.checkbox("Save Processed Image Locally")
214
- if save_image:
215
- if 'processed_img' in st.session_state:
216
- processed_img_path = os.path.join("processed_image_500x500.jpg")
217
- st.session_state.processed_img.save(processed_img_path)
218
- st.success(f"Image saved as `{processed_img_path}`")
219
- else:
220
- st.warning("No processed image to save.")
221
-
222
- # Optional: Rename Files
223
  if st.button("Rename Files"):
224
- if 'processed_img' in st.session_state:
225
- file_ext = str(np.random.randint(100))
226
- new_img_name = f"img_processed_{file_ext}.jpg"
227
- processed_img_path = "processed_image_500x500.jpg"
228
- if os.path.exists(processed_img_path):
229
- os.rename(processed_img_path, new_img_name)
230
-
231
- # Save parameters and description
232
- params_path = f"parameters_{file_ext}.json"
233
- description_path = f"description_{file_ext}.txt"
234
-
235
- pd.DataFrame([params]).to_json(params_path, orient="records")
236
- with open(description_path, "w") as f:
237
- f.write(description)
238
-
239
- st.success(f"Files renamed to `{new_img_name}`, `{params_path}`, and `{description_path}`")
240
- else:
241
- st.warning("No processed image to rename.")
 
1
+ '''
2
+ an image processing tool that allows users to upload microscope images,
3
+ adjust the view with zoom and enhancement controls, and save the processed
4
+ image along with annotations. The tool uses OpenCV for image processing and
5
+ PIL for image enhancements. The processed image can be saved locally or
6
+ exported as a zip file containing the processed image, description, and
7
+ parameters. The tool also provides options to rename the processed image and
8
+ associated files.
9
+
10
+ The tool consists of the following components:
11
+ 1. File Uploader: Allows users to upload microscope images in JPG or PNG format.
12
+ 2. Image Controls: Provides sliders to adjust the zoom, contrast, brightness, and sharpness of the image.
13
+ 3. Processed Image Display: Displays the processed image after applying the adjustments.
14
+ 4. Original Image Display: Displays the original image uploaded by the user.
15
+ 5. Save and Export Options: Allows users to add annotations, prepare a zip file for download, save the processed image locally, and rename the processed image and associated files.
16
+
17
+ To run the tool:
18
+ 1. Save the script as `cell_exp_past.py`.
19
+ 2. Run the script in a Python environment.
20
+ ```python
21
+ streamlit run cell_exp_past.py
22
+ ```
23
+ 3. Open the provided local URL in a web browser.
24
+ 4. Upload microscope images and adjust the image view.
25
+ 5. Apply adjustments and save the processed image with annotations.
26
+ 6. Download the processed image and annotations as a zip file.
27
+ 7. Save the processed image locally or rename the processed image and
28
+ associated files.
29
+ '''
30
+
31
  import streamlit as st
32
  from PIL import Image, ImageEnhance
33
  import pandas as pd
 
36
  import os
37
  import tempfile
38
  import zipfile
39
+ import json
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ def zoom_at(img, x, y, zoom):
42
+ w, h = img.size
43
+ zoom2 = zoom * 2
44
+ img = img.crop((x - w / zoom2, y - h / zoom2,
45
+ x + w / zoom2, y + h / zoom2))
46
+ return img.resize((w, h), Image.LANCZOS)
47
 
48
+ st.title("Cell Explorer")
 
 
49
 
50
+ uploaded_files = st.file_uploader("Upload Images", accept_multiple_files=True, type="jpg")
 
 
 
 
 
 
 
 
 
51
 
52
  if uploaded_files:
53
+ img_index = st.selectbox("Select Image", range(len(uploaded_files)))
54
+ x = st.slider("X Coordinate", 0, 500, 205)
55
+ y = st.slider("Y Coordinate", 0, 500, 250)
56
+ zoom = st.slider("Zoom", 1, 10, 5)
57
+ contrast = st.slider("Contrast", 0.0, 5.0, 1.0)
58
+ brightness = st.slider("Brightness", 0.0, 5.0, 1.0)
59
+ sharpness = st.slider("Sharpness", 0.0, 2.0, 1.0)
60
+ save_image = st.checkbox("Save Image")
61
 
62
+ img_data = uploaded_files[img_index].read()
63
+ img = Image.open(io.BytesIO(img_data)).resize((500, 500))
64
+ img_zoomed = zoom_at(img, x, y, zoom)
65
+ img_contrast = ImageEnhance.Contrast(img_zoomed).enhance(contrast)
66
+ img_bright = ImageEnhance.Brightness(img_contrast).enhance(brightness)
67
+ img_sharp = ImageEnhance.Sharpness(img_bright).enhance(sharpness)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
+ if save_image:
70
+ img_sharp.save("image-processed.jpg")
71
+ st.success("Image saved as image-processed.jpg")
72
 
73
+ st.image(img_sharp, caption="Processed Image", use_column_width=True)
 
 
74
 
75
+ description = st.text_area("Describe the image", "")
76
+ if st.button("Save Description"):
77
+ with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt') as f:
78
+ f.write(description)
79
+ desc_file = f.name
80
+ st.success("Description saved.")
81
 
82
+ if st.button("Save Image Parameters"):
 
83
  params = {
84
  "coordinates_x": x,
85
  "coordinates_y": y,
 
88
  "brightness": brightness,
89
  "sharpness": sharpness
90
  }
91
+ with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.json') as f:
92
+ json.dump(params, f)
93
+ params_file = f.name
94
+ st.success("Parameters saved.")
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  if st.button("Rename Files"):
97
+ file_ext = str(np.random.randint(100))
98
+ os.rename("image-processed.jpg", f"img_processed{file_ext}.jpg")
99
+ os.rename("saved_image_parameters.json", f"saved_image_parameters{file_ext}.json")
100
+ os.rename("saved_image_description.txt", f"saved_image_description{file_ext}.txt")
101
+ st.success("Files renamed successfully")
102
+
103
+ if st.button("Export to ZIP"):
104
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.zip') as zipf:
105
+ with zipfile.ZipFile(zipf.name, 'w') as z:
106
+ if 'desc_file' in locals():
107
+ z.write(desc_file, os.path.basename(desc_file))
108
+ if 'params_file' in locals():
109
+ z.write(params_file, os.path.basename(params_file))
110
+ with open(zipf.name, 'rb') as f:
111
+ st.download_button("Download ZIP", f, "annotations.zip")