Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
ArthurDelannoyazerty committed Oct 16, 2023
2 parents d7eb8dd + fc16f8c commit 42cae5d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 132 deletions.
58 changes: 53 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# OpenCV-GUI
A graphical interface for the OpenCV functions and more. This let you create interactively a pipeline of transformation for the seleted image.
A graphical interface for the OpenCV functions and more. This let you create an interactive pipeline of transformation for the selected image.

**The pipeline of transformation can be exported to python code by just pressing a button !!**
**You can export the pipeline to python code or download the images by just pressing a button !!**

# Getting started
Just download the latest release and execute the *.exe* file. Make sure that the *commands.txt* file is in the same directory as the *.exe* file (You can create a shortcut by right clicking).
Just download the latest release and execute the *.exe* file. Make sure that the *commands.txt* file is in the same directory as the *.exe* file.

### Create the environment :
```
Expand All @@ -17,7 +17,7 @@ conda env create -f environment/environment.yml
![GUI Explained](assets/gui_explained.jpg)

# A detail
If you want to use some functions that only apply to 1 channel image like Canny, Threshold, Gradient, Morph... You need to transform a RGB image to a 1 channel image using "COLOR - Colorspace (grayscale)" or "COLOR - Channel".
If you want to use some functions that only apply to 1 channel image like Canny, Threshold, Gradient, Morph... You need to transform your RGB image to a 1 channel image using "COLOR - Colorspace (grayscale)" or "COLOR - Channel".

# Want to help the project ?
You can clone or fork the repo as you wish. The pulls request still need the approval of the admin for security.
Expand All @@ -28,7 +28,7 @@ Don't hesitate to ask in the github page of this project.
# Command file
The command file located in the same directory as the *.exe* file contains all the functions that transform the image.

This file is made to be modified by the user if needed. For now the code still need to be modified by hand for each new transformation that the user add. The user can still modify the current transforamtions. There is a particular structure that needs to be followed.
This file is made to be modified by the user if needed. There is a particular structure that needs to be followed.

This file contains a series of nested python dictionnary that provide information about how the image is transformed, with which parameters and at what condition. Because of the nature of Python dictionnaries, each name must be differents from another in the same level of dictionnaries

Expand Down Expand Up @@ -76,3 +76,51 @@ Here is the structure :
# Other transformations ...
}
```

And here is an example :

```python
{
'THRESH - Simple': {
'command': 'cv.threshold(image, thresh_value, max_value, thresh_type)',
'number_parameters' : 4, # 4 parameters : 1 image, 2 sliders, 1 menu
'condition': 'len(image.shape)==2', # Image in 1 dimension
'gui':{
'slider':{
'number_slider': 2,
'slider0': {
'name': 'Thresh Value', # visual name
'variable_name': 'thresh_value', # name used in 'command'
'min_value': '0',
'max_value': '255',
'step':'1',
'default_value': '128'
},
'slider1': {
'name': 'Max Value',
'variable_name': 'max_value',
'min_value': '0',
'max_value': '255',
'step':'1',
'default_value': '255'
}
},
'menu':{
'number_menu': 1,
'menu0': {
'name': 'Threshold Type',
'variable_name': 'thresh_type',
'menu_item':{
'Binary' : cv.THRESH_BINARY,
'Binary Inverted': cv.THRESH_BINARY_INV,
'Truncate': cv.THRESH_TRUNC,
'To Zero': cv.THRESH_TOZERO,
'To Zero Inverted': cv.THRESH_TOZERO_INV,
'Otsu': cv.THRESH_OTSU
}
}
}
}
}, ...# Other transformations ...
}
```
3 changes: 2 additions & 1 deletion src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from cv2 import cvtColor, imdecode, imencode, COLOR_BGR2RGB, IMREAD_UNCHANGED
from numpy import fromfile, uint8
from sys import argv, exit
from functools import partial

from transformermanager import TransformerManager
from transformer import Transformer
Expand Down Expand Up @@ -427,7 +428,7 @@ def update_transformation_buttons(self):
image = self.pipeline[self.index_current_img].img_array # used for eval(condition)
if eval(condition_str):
button = QPushButton(transformation)
button.clicked.connect(self.transformer_manager.list_function_transformation[index])
button.clicked.connect(partial(self.transformer_manager.transformation_saver,transformation)) # send "transformation" to the function "transformation_saver"
self.container_transformation_buttons_layout.addWidget(button)

def update_transformation_parameters_frame(self):
Expand Down
2 changes: 1 addition & 1 deletion src/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def execute_transformation(self, index):
try:
item_current.img_array = self.transformer.transform(item_before, item_current)
except:
self.function_to_call_error("An error occured in the transformation pipeline ("+ str(index-2)+ "->"+ str(index-1) +"). Action cancelled.")
self.function_to_call_error("An error occured in the transformation pipeline ("+ str(index-1)+ "->"+ str(index) +"). Action cancelled.")
raise Exception("Error in the pipeline."+ str(index-2)+ "->"+ str(index-1))

def update_from_index(self, index=1):
Expand Down
126 changes: 1 addition & 125 deletions src/transformermanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,6 @@ def __init__(self, main_window, pipeline, transformer):
self.main_window = main_window
self.pipeline = pipeline
self.transformer = transformer
self.list_function_transformation = [ # Used from main.py to connect to the transformation button to the right function below
self.alert_draw_line,
self.alert_draw_rectangle,
self.alert_draw_circle,
self.alert_draw_ellipse,
self.alert_crop,
self.alert_rotation_zoom,
self.alert_select_channel,
self.alert_colorspacechange,
self.alert_simple_blur,
self.alert_gaussian_blur,
self.alert_median_blur,
self.alert_bilateral_filtering,
self.alert_luminosity_contrast,
self.alert_gaussian_noise,
self.alert_salt_pepper_noise,
self.alert_poisson_noise,
self.alert_speckle_noise,
self.alert_filter2d,
self.alert_threshold1d,
self.alert_adaptive_threshold1d,
self.alert_gradient_laplacian,
self.alert_gradient_sobel,
self.alert_gradient_canny,
self.alert_morph
]

def transformation_saver(self, key_command):
"""Modify the transformation in pipeline"""
Expand Down Expand Up @@ -85,102 +59,4 @@ def get_default_transformation_parameters(self, key_command):
default_value = list(current_slider['menu_item'].values())[0]
dict_default_values[var_name] = default_value

return dict_default_values

# All these functions takes the main name of the commands file and send it to the 'transformation_saver' method

def alert_draw_line(self):
key_command = list(self.main_window.transformer.commands.keys())[0]
self.transformation_saver(key_command)

def alert_draw_rectangle(self):
key_command = list(self.main_window.transformer.commands.keys())[1]
self.transformation_saver(key_command)

def alert_draw_circle(self):
key_command = list(self.main_window.transformer.commands.keys())[2]
self.transformation_saver(key_command)

def alert_draw_ellipse(self):
key_command = list(self.main_window.transformer.commands.keys())[3]
self.transformation_saver(key_command)

def alert_crop(self):
key_command = list(self.main_window.transformer.commands.keys())[4]
self.transformation_saver(key_command)

def alert_rotation_zoom(self):
key_command = list(self.main_window.transformer.commands.keys())[5]
self.transformation_saver(key_command)

def alert_select_channel(self):
key_command = list(self.main_window.transformer.commands.keys())[6]
self.transformation_saver(key_command)

def alert_colorspacechange(self):
key_command = list(self.main_window.transformer.commands.keys())[7]
self.transformation_saver(key_command)

def alert_simple_blur(self):
key_command = list(self.main_window.transformer.commands.keys())[8]
self.transformation_saver(key_command)

def alert_gaussian_blur(self):
key_command = list(self.main_window.transformer.commands.keys())[9]
self.transformation_saver(key_command)

def alert_median_blur(self):
key_command = list(self.main_window.transformer.commands.keys())[10]
self.transformation_saver(key_command)

def alert_bilateral_filtering(self):
key_command = list(self.main_window.transformer.commands.keys())[11]
self.transformation_saver(key_command)

def alert_luminosity_contrast(self):
key_command = list(self.main_window.transformer.commands.keys())[12]
self.transformation_saver(key_command)

def alert_gaussian_noise(self):
key_command = list(self.main_window.transformer.commands.keys())[13]
self.transformation_saver(key_command)

def alert_salt_pepper_noise(self):
key_command = list(self.main_window.transformer.commands.keys())[14]
self.transformation_saver(key_command)

def alert_poisson_noise(self):
key_command = list(self.main_window.transformer.commands.keys())[15]
self.transformation_saver(key_command)

def alert_speckle_noise(self):
key_command = list(self.main_window.transformer.commands.keys())[16]
self.transformation_saver(key_command)

def alert_filter2d(self):
key_command = list(self.main_window.transformer.commands.keys())[17]
self.transformation_saver(key_command)

def alert_threshold1d(self):
key_command = list(self.main_window.transformer.commands.keys())[18]
self.transformation_saver(key_command)

def alert_adaptive_threshold1d(self):
key_command = list(self.main_window.transformer.commands.keys())[19]
self.transformation_saver(key_command)

def alert_gradient_laplacian(self):
key_command = list(self.main_window.transformer.commands.keys())[20]
self.transformation_saver(key_command)

def alert_gradient_sobel(self):
key_command = list(self.main_window.transformer.commands.keys())[21]
self.transformation_saver(key_command)

def alert_gradient_canny(self):
key_command = list(self.main_window.transformer.commands.keys())[22]
self.transformation_saver(key_command)

def alert_morph(self):
key_command = list(self.main_window.transformer.commands.keys())[23]
self.transformation_saver(key_command)
return dict_default_values

0 comments on commit 42cae5d

Please sign in to comment.