Skip to content

Commit 8d4e806

Browse files
committed
Fixed a bug with color spaces, added the ability to select the type, color and transparency of the fill, added the ability to delete a particle from the data set.
1 parent ac4f911 commit 8d4e806

File tree

7 files changed

+210
-83
lines changed

7 files changed

+210
-83
lines changed

particleanalyzer/core/ParticleAnalyzer.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ def analyze_image(
157157
outline_color,
158158
show_fillPoly,
159159
show_polylines,
160+
fill_type_color,
161+
fill_color,
162+
fill_alpha,
160163
api_key: bool,
161164
request: gr.Request,
162165
pr=gr.Progress(),
@@ -229,6 +232,9 @@ def analyze_image(
229232
"outline_color": outline_color,
230233
"show_fillPoly": show_fillPoly,
231234
"show_polylines": show_polylines,
235+
"fill_type_color": fill_type_color,
236+
"fill_color": fill_color,
237+
"fill_alpha": fill_alpha,
232238
}
233239

234240
# Выбор стратегии обработки
@@ -619,12 +625,19 @@ def get_feret(contour, angles=np.arange(0, 180, 1)):
619625
mask_img = np.zeros_like(config["gray_image"], dtype=np.uint8)
620626
cv2.fillPoly(mask_img, [points], 255)
621627
mean_intensity = cv2.mean(config["gray_image"], mask=mask_img)[0]
622-
623628
# Отрисовка контура и Feret-линий (опционально)
624629
if config["show_fillPoly"]:
625630
overlay = config["output_image"].copy()
626-
cv2.fillPoly(overlay, [points], self.get_random_color())
627-
alpha = 0.3
631+
cv2.fillPoly(
632+
overlay,
633+
[points],
634+
(
635+
self.get_random_color()
636+
if config["fill_type_color"] == "Random"
637+
else self.rgba_to_bgr(config["fill_color"])
638+
),
639+
)
640+
alpha = config["fill_alpha"]
628641
cv2.addWeighted(
629642
overlay,
630643
alpha,

particleanalyzer/core/languages.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@
134134
"Включить контур?": "Включить контур?",
135135
"Цвет контура": "Цвет контура",
136136
"Включить заливку?": "Включить заливку?",
137+
"Тип заливки": "Тип заливки",
138+
"Цвет заливки": "Цвет заливки",
139+
"Прозрачность заливки": "Прозрачность заливки",
140+
"Удалить частицу": "Удалить частицу",
137141
},
138142
"en": {
139143
"Подготовка...": "Initializing...",
@@ -256,6 +260,10 @@
256260
"Включить контур?": "Enable outline?",
257261
"Цвет контура": "Outline color",
258262
"Включить заливку?": "Enable fill?",
263+
"Тип заливки": "Fill Type",
264+
"Цвет заливки": "Fill Color",
265+
"Прозрачность заливки": "Fill Transparency",
266+
"Удалить частицу": "Remove particle",
259267
},
260268
"zh-cn": {
261269
"Подготовка...": "初始化中...",
@@ -378,6 +386,10 @@
378386
"Включить контур?": "启用轮廓?",
379387
"Цвет контура": "轮廓颜色",
380388
"Включить заливку?": "启用填充?",
389+
"Тип заливки": "填充类型",
390+
"Цвет заливки": "填充颜色",
391+
"Прозрачность заливки": "填充透明度",
392+
"Удалить частицу": "去除颗粒",
381393
},
382394
"zh-tw": {
383395
"Подготовка...": "初始化中...",
@@ -508,6 +520,10 @@
508520
"Включить контур?": "啟用輪廓?",
509521
"Цвет контура": "輪廓顏色",
510522
"Включить заливку?": "啟用填充?",
523+
"Тип заливки": "填滿類型",
524+
"Цвет заливки": "填滿顏色",
525+
"Прозрачность заливки": "填滿透明度",
526+
"Удалить частицу": "去除顆粒",
511527
},
512528
}
513529

particleanalyzer/core/ui.py

Lines changed: 115 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
translate_chatbot,
1717
statistic_an,
1818
select_particle_from_image,
19+
particle_removal,
1920
)
2021
from particleanalyzer.core.about import about_ru
2122
from particleanalyzer.core.parameter_information import reference_ru
@@ -172,13 +173,20 @@ def create_interface(api_key):
172173
elem_id="output-image",
173174
)
174175
with gr.Row(visible=False) as output_table_image2_row:
175-
output_table_image2 = gr.Dataframe(
176-
value=empty_df_ParticleCharacteristics,
177-
label=i18n("Характеристики частицы"),
178-
interactive=True,
179-
elem_id="dataframe-table",
180-
show_copy_button=True,
181-
)
176+
with gr.Column():
177+
output_table_image2 = gr.Dataframe(
178+
value=empty_df_ParticleCharacteristics,
179+
label=i18n("Характеристики частицы"),
180+
interactive=True,
181+
elem_id="dataframe-table",
182+
show_copy_button=True,
183+
)
184+
delete_row = gr.Button(
185+
value=i18n("Удалить частицу"),
186+
icon="https://rybakov-k.ru/assets/icon/incorrect.png",
187+
elem_id="delete-row-btn",
188+
elem_classes="custom-btn btn-delete-row",
189+
)
182190

183191
with gr.Row(visible=False) as scale_input_row:
184192
scale_input = gr.Number(
@@ -189,24 +197,18 @@ def create_interface(api_key):
189197

190198
with gr.Row(elem_id="button-row"):
191199
with gr.Column(min_width=140):
192-
process_button = gr.HTML(
193-
f"""
194-
<button class="custom-btn btn-analyze" id="process-button">
195-
<img src='https://rybakov-k.ru/assets/icon/icons8-химия-50.png'
196-
alt='Analyze icon'/>
197-
{i18n('Анализировать')}
198-
</button>
199-
"""
200+
process_button = gr.Button(
201+
value=i18n("Анализировать"),
202+
icon="https://rybakov-k.ru/assets/icon/icons8-химия-50.png",
203+
elem_id="process-button",
204+
elem_classes="custom-btn btn-analyze",
200205
)
201206
with gr.Column(min_width=140):
202-
clear_button = gr.HTML(
203-
f"""
204-
<button class="custom-btn btn-clear" id="clear-btn">
205-
<img src='https://rybakov-k.ru/assets/icon/icons8-метла-50.png'
206-
alt='Clear icon'/>
207-
{i18n('Очистить')}
208-
</button>
209-
"""
207+
clear_button = gr.Button(
208+
value=i18n("Очистить"),
209+
icon="https://rybakov-k.ru/assets/icon/icons8-метла-50.png",
210+
elem_id="clear-btn",
211+
elem_classes="custom-btn btn-clear",
210212
)
211213

212214
with gr.Row(elem_id="example-row") as in_image_example_row:
@@ -288,24 +290,18 @@ def create_interface(api_key):
288290
)
289291
with gr.Row(elem_id="button-row"):
290292
with gr.Column(min_width=140):
291-
llm_run = gr.HTML(
292-
f"""
293-
<button class="custom-btn btn-ai-run" id="ai-run-btn"">
294-
<img src='https://rybakov-k.ru/assets/icon/ai.png'
295-
alt='Analyze icon'/>
296-
{i18n('Запустить ИИ-анализ')}
297-
</button>
298-
"""
293+
llm_run = gr.Button(
294+
value=i18n("Запустить ИИ-анализ"),
295+
icon="https://rybakov-k.ru/assets/icon/ai.png",
296+
elem_id="ai-run-btn",
297+
elem_classes="custom-btn btn-ai-run",
299298
)
300299
with gr.Column(min_width=140):
301-
cancel_llm_button = gr.HTML(
302-
f"""
303-
<button class="custom-btn btn-ai-cancel" id="ai-cancel-btn"">
304-
<img src='https://rybakov-k.ru/assets/icon/incorrect.png'
305-
alt='Clear icon'/>
306-
{i18n('Отменить')}
307-
</button>
308-
"""
300+
cancel_llm_button = gr.Button(
301+
value=i18n("Отменить"),
302+
icon="https://rybakov-k.ru/assets/icon/incorrect.png",
303+
elem_id="ai-cancel-btn",
304+
elem_classes="custom-btn btn-ai-cancel",
309305
)
310306

311307
with gr.Tab(i18n("Файлы"), id=4):
@@ -324,24 +320,18 @@ def create_interface(api_key):
324320
)
325321
with gr.Row(elem_id="button-row"):
326322
with gr.Column(min_width=140):
327-
yes_button = gr.HTML(
328-
f"""
329-
<button class="custom-btn btn-yes" id="yes-btn"">
330-
<img src='https://rybakov-k.ru/assets/icon/like.png'
331-
alt='Analyze icon'/>
332-
{i18n('Да')}
333-
</button>
334-
"""
323+
yes_button = gr.Button(
324+
value=i18n("Да"),
325+
icon="https://rybakov-k.ru/assets/icon/like.png",
326+
elem_id="yes-btn",
327+
elem_classes="custom-btn btn-yes",
335328
)
336329
with gr.Column(min_width=140):
337-
no_button = gr.HTML(
338-
f"""
339-
<button class="custom-btn btn-no" id="no-btn"">
340-
<img src='https://rybakov-k.ru/assets/icon/dislike.png'
341-
alt='Clear icon'/>
342-
{i18n('Нет')}
343-
</button>
344-
"""
330+
no_button = gr.Button(
331+
value=i18n("Нет"),
332+
icon="https://rybakov-k.ru/assets/icon/dislike.png",
333+
elem_id="no-btn",
334+
elem_classes="custom-btn btn-no",
345335
)
346336

347337
with gr.Tab(i18n("Настройки"), elem_id="setting"):
@@ -406,15 +396,15 @@ def create_interface(api_key):
406396
value="1024x1024",
407397
label=i18n("Разрешение изображения"),
408398
)
409-
with gr.Row() as number_detections_row:
410-
number_detections = gr.Slider(
411-
minimum=1,
412-
maximum=10000,
413-
value=1000,
414-
step=100,
415-
label=i18n("Максимальное количество обнаружений"),
416-
elem_id="number-detections",
417-
)
399+
with gr.Column():
400+
number_detections = gr.Slider(
401+
minimum=1,
402+
maximum=10000,
403+
value=1000,
404+
step=100,
405+
label=i18n("Количество обнаружений"),
406+
elem_id="number-detections",
407+
)
418408
with gr.Row(visible=False):
419409
round_value = gr.Dropdown(
420410
[0, 1, 2, 3, 4, 5, 6],
@@ -435,22 +425,39 @@ def create_interface(api_key):
435425
label=i18n("Включить"),
436426
info=i18n("Включить отображение диаметров Ферета?"),
437427
)
438-
with gr.Column(min_width=150):
428+
with gr.Column():
439429
show_polylines = gr.Checkbox(
440430
value=True,
441431
label=i18n("Включить"),
442432
info=i18n("Включить контур?"),
443433
)
444-
with gr.Column(min_width=300):
434+
with gr.Column():
445435
outline_color = gr.ColorPicker(
446436
value="rgb(0, 255, 0, 1)", label=i18n("Цвет контура")
447437
)
448-
with gr.Column(min_width=150):
438+
with gr.Column(min_width=100):
449439
show_fillPoly = gr.Checkbox(
450440
label=i18n("Включить"),
451441
info=i18n("Включить заливку?"),
452442
)
453-
443+
with gr.Column(min_width=250):
444+
fill_type_color = gr.Radio(
445+
("Random", "Permanent"),
446+
value="Random",
447+
label=i18n("Тип заливки"),
448+
)
449+
with gr.Column(min_width=300):
450+
fill_color = gr.ColorPicker(
451+
value="rgb(0, 255, 0, 1)", label=i18n("Цвет заливки")
452+
)
453+
with gr.Column():
454+
fill_alpha = gr.Slider(
455+
minimum=0,
456+
maximum=1,
457+
value=0.3,
458+
step=0.01,
459+
label=i18n("Прозрачность заливки"),
460+
)
454461
with gr.Tab(i18n("О программе")):
455462
gr.HTML(i18n(about_ru))
456463
with gr.Row(visible=False) as slider:
@@ -503,6 +510,7 @@ def create_interface(api_key):
503510
label=f"I [{i18n('ед.')}]",
504511
)
505512
# with gr.Row():
513+
# apply_filter = gr.Button(value=i18n('Применить фильтр'), icon='https://rybakov-k.ru/assets/icon/dislike.png', elem_id='filter-btn', elem_classes='custom-btn btn-f')
506514
# apply_filter = gr.HTML(
507515
# f"""
508516
# <button class="custom-btn btn-f" id="filter-btn" style="display: flex; align-items: center; gap: 8px;">
@@ -534,6 +542,9 @@ def create_interface(api_key):
534542
outline_color,
535543
show_fillPoly,
536544
show_polylines,
545+
fill_type_color,
546+
fill_color,
547+
fill_alpha,
537548
api_key,
538549
],
539550
outputs=[
@@ -564,7 +575,39 @@ def create_interface(api_key):
564575
)
565576

566577
process_button.click(translate_chatbot, None, chatbot)
567-
578+
delete_row.click(
579+
particle_removal,
580+
inputs=[output_table_image2, points_df, output_table],
581+
outputs=[output_table_image2_row, points_df, output_table],
582+
).success(
583+
fn=statistic_an,
584+
inputs=[
585+
output_table,
586+
points_df,
587+
scale_selector,
588+
round_value,
589+
number_of_bins,
590+
d_max_slider,
591+
d_min_slider,
592+
theta_max_slider,
593+
theta_min_slider,
594+
e_slider,
595+
S_slider,
596+
P_slider,
597+
I_slider,
598+
im,
599+
in_image,
600+
solution,
601+
sahi_mode,
602+
outline_color,
603+
show_fillPoly,
604+
show_polylines,
605+
fill_type_color,
606+
fill_color,
607+
fill_alpha,
608+
],
609+
outputs=[output_table2, output_plot, output_image],
610+
)
568611
gr.on(
569612
triggers=[
570613
d_max_slider.release,
@@ -598,6 +641,9 @@ def create_interface(api_key):
598641
outline_color,
599642
show_fillPoly,
600643
show_polylines,
644+
fill_type_color,
645+
fill_color,
646+
fill_alpha,
601647
],
602648
outputs=[output_table2, output_plot, output_image],
603649
)
@@ -631,7 +677,6 @@ def create_interface(api_key):
631677
outputs=[
632678
slice_row,
633679
slice_row2,
634-
number_detections_row,
635680
solution_and_segment_mode_row,
636681
],
637682
show_progress="hide",

0 commit comments

Comments
 (0)