Spaces:
Sleeping
Sleeping
''' | |
an image processing tool that allows users to upload microscope images, | |
adjust the view with zoom and enhancement controls, and save the processed | |
image along with annotations. The tool uses OpenCV for image processing and | |
PIL for image enhancements. The processed image can be saved locally or | |
exported as a zip file containing the processed image, description, and | |
parameters. The tool also provides options to rename the processed image and | |
associated files. | |
The tool consists of the following components: | |
1. File Uploader: Allows users to upload microscope images in JPG or PNG format. | |
2. Image Controls: Provides sliders to adjust the zoom, contrast, brightness, and sharpness of the image. | |
3. Processed Image Display: Displays the processed image after applying the adjustments. | |
4. Original Image Display: Displays the original image uploaded by the user. | |
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. | |
To run the tool: | |
1. Save the script as `cell_exp_past.py`. | |
2. Run the script in a Python environment. | |
```python | |
streamlit run cell_exp_past.py | |
``` | |
3. Open the provided local URL in a web browser. | |
4. Upload microscope images and adjust the image view. | |
5. Apply adjustments and save the processed image with annotations. | |
6. Download the processed image and annotations as a zip file. | |
7. Save the processed image locally or rename the processed image and | |
associated files. | |
''' | |
import streamlit as st | |
from PIL import Image, ImageEnhance | |
import pandas as pd | |
import numpy as np | |
import io | |
import os | |
import tempfile | |
import zipfile | |
import json | |
def zoom_at(img, x, y, zoom): | |
''' | |
increase the zoom level of the image at a specific point (x, y). | |
Parameters: | |
img (PIL.Image): The input image. | |
x (int): The x-coordinate of the point. | |
y (int): The y-coordinate of the point. | |
zoom (float): The zoom level. | |
Returns: | |
PIL.Image: The zoomed image. | |
Examples: | |
>>> img = Image.open('image.jpg') | |
>>> zoomed_img = zoom_at(img, 100, 100, 2.0) | |
''' | |
w, h = img.size | |
zoom2 = zoom * 2 | |
img = img.crop((x - w / zoom2, y - h / zoom2, | |
x + w / zoom2, y + h / zoom2)) | |
return img.resize((w, h), Image.LANCZOS) | |
st.title("CLL Image Processing Tool") | |
st.write('''This tool allows you to upload microscope images, | |
adjust the view with zoom and enhancement controls, | |
and save the processed image along with annotations. | |
You can also export the processed image, description, | |
and parameters as a zip file. | |
''') | |
uploaded_files = st.file_uploader("Upload Images", accept_multiple_files=True, type="jpg") | |
if uploaded_files: | |
img_index = st.selectbox("Select Image", range(len(uploaded_files))) | |
x = st.slider("X Coordinate", 0, 500, 205) | |
y = st.slider("Y Coordinate", 0, 500, 250) | |
zoom = st.slider("Zoom", 1.0, 10.0, 0.5) | |
contrast = st.slider("Contrast", 0.0, 5.0, 1.0) | |
brightness = st.slider("Brightness", 0.0, 5.0, 1.0) | |
sharpness = st.slider("Sharpness", 0.0, 2.0, 1.0) | |
save_image = st.checkbox("Save Image") | |
img_data = uploaded_files[img_index].read() | |
img = Image.open(io.BytesIO(img_data)).resize((500, 500)) | |
img_zoomed = zoom_at(img, x, y, zoom) | |
img_contrast = ImageEnhance.Contrast(img_zoomed).enhance(contrast) | |
img_bright = ImageEnhance.Brightness(img_contrast).enhance(brightness) | |
img_sharp = ImageEnhance.Sharpness(img_bright).enhance(sharpness) | |
if save_image: | |
processed_image_path = "image-processed.jpg" | |
img_sharp.save(processed_image_path) | |
st.session_state['processed_image_path'] = processed_image_path | |
st.success(f"Image saved as {processed_image_path}") | |
st.image(img_sharp, caption="Processed Image", use_container_width=True) | |
description = st.text_area("Describe the image", "") | |
if st.button("Save Description"): | |
with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt') as f: | |
f.write(description) | |
desc_file = f.name | |
st.session_state['desc_file'] = desc_file | |
st.success("Description saved.") | |
if st.button("Save Image Parameters"): | |
params = { | |
"coordinates_x": x, | |
"coordinates_y": y, | |
"zoom": zoom, | |
"contrast": contrast, | |
"brightness": brightness, | |
"sharpness": sharpness | |
} | |
with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.json') as f: | |
json.dump(params, f) | |
params_file = f.name | |
st.session_state['params_file'] = params_file | |
st.success("Parameters saved.") | |
if st.button("Rename Files"): | |
file_ext = str(np.random.randint(100)) | |
processed_image_path = st.session_state.get('processed_image_path', None) | |
desc_file = st.session_state.get('desc_file', None) | |
params_file = st.session_state.get('params_file', None) | |
if processed_image_path and os.path.exists(processed_image_path): | |
try: | |
new_image_name = f"img_processed{file_ext}.jpg" | |
os.rename(processed_image_path, new_image_name) | |
st.session_state['processed_image_path'] = new_image_name # Update session state | |
st.success(f"Image renamed to {new_image_name}") | |
except FileNotFoundError: | |
st.error(f"{processed_image_path} not found.") | |
else: | |
st.error("Processed image not found.") | |
if params_file and os.path.exists(params_file): | |
try: | |
new_params_name = f"saved_image_parameters{file_ext}.json" | |
os.rename(params_file, new_params_name) | |
st.session_state['params_file'] = new_params_name # Update session state | |
st.success(f"Parameters file renamed to {new_params_name}") | |
except FileNotFoundError: | |
st.error(f"{params_file} not found.") | |
else: | |
st.error("Saved image parameters file not found.") | |
if desc_file and os.path.exists(desc_file): | |
try: | |
new_desc_name = f"saved_image_description{file_ext}.txt" | |
os.rename(desc_file, new_desc_name) | |
st.session_state['desc_file'] = new_desc_name # Update session state | |
st.success(f"Description file renamed to {new_desc_name}") | |
except FileNotFoundError: | |
st.error(f"{desc_file} not found.") | |
else: | |
st.error("Saved image description file not found.") | |
st.success("Files renamed successfully") | |
if st.button("Export to ZIP"): | |
desc_file = st.session_state.get('desc_file', None) | |
params_file = st.session_state.get('params_file', None) | |
processed_image_path = st.session_state.get('processed_image_path', None) | |
with tempfile.NamedTemporaryFile(delete=False, suffix='.zip') as zipf: | |
with zipfile.ZipFile(zipf.name, 'w') as z: | |
files_added = False # Flag to check if any file is added | |
if desc_file and os.path.exists(desc_file): | |
z.write(desc_file, os.path.basename(desc_file)) | |
files_added = True | |
else: | |
st.warning("Description file not found and was not added to the ZIP.") | |
if params_file and os.path.exists(params_file): | |
z.write(params_file, os.path.basename(params_file)) | |
files_added = True | |
else: | |
st.warning("Parameters file not found and was not added to the ZIP.") | |
if processed_image_path and os.path.exists(processed_image_path): | |
z.write(processed_image_path, os.path.basename(processed_image_path)) | |
files_added = True | |
else: | |
st.warning("Processed image not found and was not added to the ZIP.") | |
# Check if the ZIP file has any content | |
if os.path.getsize(zipf.name) > 0 and files_added: | |
with open(zipf.name, 'rb') as f: | |
st.download_button("Download ZIP", f, "annotations.zip") | |
else: | |
st.error("No files were added to the ZIP. Please ensure files are saved before exporting.") | |