File size: 8,378 Bytes
95c04af
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
db79a69
95c04af
 
 
 
 
 
 
 
 
 
d48f8a3
f2deb22
 
 
 
 
 
3e5dac2
 
95c04af
3e5dac2
95c04af
db79a69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95c04af
 
 
 
 
3e5dac2
01beaea
3e5dac2
db79a69
 
 
 
 
 
 
95c04af
3e5dac2
 
95c04af
 
 
8222e7a
95c04af
 
 
 
3e5dac2
95c04af
 
 
 
 
 
3e5dac2
95c04af
55df1ea
 
 
 
3e5dac2
f8739c6
3e5dac2
95c04af
 
 
 
 
55df1ea
95c04af
3e5dac2
95c04af
0e955d7
 
 
 
 
 
 
 
95c04af
 
 
55df1ea
95c04af
0e955d7
 
95c04af
55df1ea
 
 
 
 
 
 
 
d48f8a3
 
55df1ea
 
d48f8a3
55df1ea
 
 
 
d48f8a3
 
 
 
 
 
 
55df1ea
 
 
 
d48f8a3
 
 
 
 
 
 
55df1ea
 
 
95c04af
 
 
01beaea
 
 
 
95c04af
 
d48f8a3
 
01beaea
95c04af
d48f8a3
01beaea
 
 
 
95c04af
d48f8a3
01beaea
 
 
 
 
d48f8a3
01beaea
 
 
 
d48f8a3
01beaea
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
'''
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.")