batoolset 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- batoolset/GUI/__init__.py +0 -0
- batoolset/GUI/list_gui.py +513 -0
- batoolset/GUI/multi_image_display.py +989 -0
- batoolset/GUI/open.py +325 -0
- batoolset/GUI/overlay_hints.py +45 -0
- batoolset/GUI/paint2.py +1345 -0
- batoolset/GUI/scrollablepaint.py +1152 -0
- batoolset/IJ_ROIs/__init__.py +0 -0
- batoolset/IJ_ROIs/tools.py +40 -0
- batoolset/PATH/__init__.py +0 -0
- batoolset/PATH/tools.py +79 -0
- batoolset/SQLite_tools/__init__.py +0 -0
- batoolset/SQLite_tools/tools.py +840 -0
- batoolset/__init__.py +0 -0
- batoolset/binary/__init__.py +0 -0
- batoolset/binary/tools.py +123 -0
- batoolset/binarytools/__init__.py +0 -0
- batoolset/binarytools/cell_center_detector.py +290 -0
- batoolset/clipboard_tools/__init__.py +0 -0
- batoolset/clipboard_tools/tools.py +7 -0
- batoolset/colors/__init__.py +0 -0
- batoolset/colors/colorgen.py +193 -0
- batoolset/colors/tools.py +22 -0
- batoolset/command_line/__init__.py +0 -0
- batoolset/command_line/tools.py +18 -0
- batoolset/dialogs/__init__.py +0 -0
- batoolset/dialogs/opensave.py +228 -0
- batoolset/dicts/__init__.py +0 -0
- batoolset/dicts/tools.py +299 -0
- batoolset/dims/__init__.py +0 -0
- batoolset/dims/tools.py +83 -0
- batoolset/draw/__init__.py +0 -0
- batoolset/draw/shapes/Position.py +183 -0
- batoolset/draw/shapes/__init__.py +0 -0
- batoolset/draw/shapes/automated_alignment_drawing_refactored.py +346 -0
- batoolset/draw/shapes/circle2d.py +99 -0
- batoolset/draw/shapes/compute_optimal_size_all_merged.py +317 -0
- batoolset/draw/shapes/ellipse2d.py +336 -0
- batoolset/draw/shapes/freehand2d.py +235 -0
- batoolset/draw/shapes/group.py +1830 -0
- batoolset/draw/shapes/image2d.py +2469 -0
- batoolset/draw/shapes/line2d.py +575 -0
- batoolset/draw/shapes/point2d.py +257 -0
- batoolset/draw/shapes/polygon2d.py +357 -0
- batoolset/draw/shapes/polyline2d.py +235 -0
- batoolset/draw/shapes/rect2d.py +388 -0
- batoolset/draw/shapes/rectangle2d.py +601 -0
- batoolset/draw/shapes/scalebar.py +304 -0
- batoolset/draw/shapes/serializablefont.py +126 -0
- batoolset/draw/shapes/serializableguiparams.py +10 -0
- batoolset/draw/shapes/square2d.py +103 -0
- batoolset/draw/shapes/textorientation.py +45 -0
- batoolset/draw/shapes/tools.py +467 -0
- batoolset/draw/shapes/transform2D.py +350 -0
- batoolset/draw/shapes/txt2d.py +550 -0
- batoolset/draw/widgets/__init__.py +0 -0
- batoolset/draw/widgets/col.py +343 -0
- batoolset/draw/widgets/image_group.py +248 -0
- batoolset/draw/widgets/image_organizer.py +96 -0
- batoolset/draw/widgets/paint.py +184 -0
- batoolset/draw/widgets/vectorial.py +257 -0
- batoolset/figure/__init__.py +0 -0
- batoolset/figure/alignment.py +814 -0
- batoolset/figure/column.py +1117 -0
- batoolset/figure/fig_tools.py +285 -0
- batoolset/figure/minimal_debugger_scale_etc.py +139 -0
- batoolset/figure/panel.py +697 -0
- batoolset/figure/row.py +852 -0
- batoolset/figure/user_selection.py +287 -0
- batoolset/files/__init__.py +0 -0
- batoolset/files/tools.py +1321 -0
- batoolset/images/__init__.py +0 -0
- batoolset/images/tools.py +81 -0
- batoolset/img.py +5216 -0
- batoolset/linux/__init__.py +0 -0
- batoolset/linux/tools.py +72 -0
- batoolset/lists/__init__.py +0 -0
- batoolset/lists/tools.py +436 -0
- batoolset/luts/__init__.py +0 -0
- batoolset/luts/lut_minimal_test.py +1207 -0
- batoolset/matplolib/__init__.py +0 -0
- batoolset/matplolib/tools.py +44 -0
- batoolset/np_tools/__init__.py +0 -0
- batoolset/np_tools/tools.py +252 -0
- batoolset/np_tools/trash.py +15 -0
- batoolset/pandas_tools/__init__.py +0 -0
- batoolset/pandas_tools/tools.py +880 -0
- batoolset/partials/__init__.py +0 -0
- batoolset/partials/tools.py +83 -0
- batoolset/plot_tools/__init__.py +0 -0
- batoolset/plot_tools/tools.py +70 -0
- batoolset/pyqt/__init__.py +0 -0
- batoolset/pyqt/tools.py +691 -0
- batoolset/re_tools/__init__.py +0 -0
- batoolset/re_tools/tools.py +35 -0
- batoolset/serialization/__init__.py +0 -0
- batoolset/serialization/tools.py +1192 -0
- batoolset/sets/__init__.py +0 -0
- batoolset/sets/tools.py +109 -0
- batoolset/settings/__init__.py +0 -0
- batoolset/settings/global_settings.py +134 -0
- batoolset/strings/__init__.py +0 -0
- batoolset/strings/tools.py +225 -0
- batoolset/ta/__init__.py +0 -0
- batoolset/ta/database/__init__.py +0 -0
- batoolset/ta/database/advanced_sql_plotter.py +1170 -0
- batoolset/ta/database/my_qt_table.py +79 -0
- batoolset/ta/database/preview_and_edit_sqlite_db.py +405 -0
- batoolset/ta/database/sql.py +2141 -0
- batoolset/ta/database/sql_column_name_dialog.py +122 -0
- batoolset/ta/measurements/TAmeasures.py +2226 -0
- batoolset/ta/measurements/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/get_point_on_surface_if_centroid_is_bad.py +175 -0
- batoolset/ta/measurements/measurements3D/height_map_to_projection.py +82 -0
- batoolset/ta/measurements/measurements3D/measures3D.py +208 -0
- batoolset/ta/measurements/measurements3D/triangulate.py +331 -0
- batoolset/ta/measurements/nematic.py +562 -0
- batoolset/ta/measurements/nematic_measurements.py +107 -0
- batoolset/ta/segmentation/__init__.py +0 -0
- batoolset/ta/segmentation/neo_wshed.py +314 -0
- batoolset/ta/selections/__init__.py +0 -0
- batoolset/ta/selections/selection.py +329 -0
- batoolset/ta/tracking/__init__.py +0 -0
- batoolset/ta/tracking/last_tracking_based_on_matching_or_on_translation_from_mermaid_warp.py +653 -0
- batoolset/ta/tracking/local_to_track_correspondance.py +138 -0
- batoolset/ta/tracking/rapid_detection_of_vertices.py +517 -0
- batoolset/ta/tracking/registration.py +108 -0
- batoolset/ta/tracking/swap_detector_and_fixer.py +296 -0
- batoolset/ta/tracking/track_correction.py +238 -0
- batoolset/ta/tracking/tracking_error_detector_and_fixer.py +3099 -0
- batoolset/ta/tracking/tracking_yet_another_approach_pyramidal_registration_n_neo_swapping_correction.py +725 -0
- batoolset/ta/utils/TA_tools.py +43 -0
- batoolset/ta/utils/__init__.py +0 -0
- batoolset/ta/utils/rps_tools.py +1783 -0
- batoolset/tests/__init__.py +0 -0
- batoolset/tests/rps_tools.py +51 -0
- batoolset/tests/tools.py +10 -0
- batoolset/tools/__init__.py +0 -0
- batoolset/tools/early_stopper_class.py +9 -0
- batoolset/tools/guided_data_recoverer.py +110 -0
- batoolset/tools/logger.py +100 -0
- batoolset/tools/mytimer.py +31 -0
- batoolset/tools/prompt_color.py +160 -0
- batoolset/tools/qthandler.py +118 -0
- batoolset/uitools/__init__.py +0 -0
- batoolset/uitools/blinker.py +56 -0
- batoolset/unsafe/__init__.py +0 -0
- batoolset/unsafe/tools.py +115 -0
- batoolset/utils/__init__.py +0 -0
- batoolset/utils/commontools.py +158 -0
- batoolset/utils/loadlist.py +728 -0
- batoolset/version.py +10 -0
- batoolset/xml/__init__.py +0 -0
- batoolset/xml/tools.py +65 -0
- batoolset/zip_tools/__init__.py +0 -0
- batoolset/zip_tools/tools.py +76 -0
- batoolset-0.1.0.dist-info/LICENSE +24 -0
- batoolset-0.1.0.dist-info/METADATA +45 -0
- batoolset-0.1.0.dist-info/RECORD +162 -0
- batoolset-0.1.0.dist-info/WHEEL +5 -0
- batoolset-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# TODO make these things combined with pack and align commands and make loops
|
|
2
|
+
# this way I can make any component at any specific position !!!
|
|
3
|
+
# this is quite good I think
|
|
4
|
+
import copy
|
|
5
|
+
import traceback
|
|
6
|
+
from itertools import groupby
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
from batoolset.figure.alignment import packing_modes
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Define a sorting key function to sort objects based on their positions
|
|
13
|
+
def sorting_key(obj):
|
|
14
|
+
try:
|
|
15
|
+
return tuple(sorted(obj.items()))
|
|
16
|
+
except:
|
|
17
|
+
try:
|
|
18
|
+
return tuple(sorted(obj.placement.get_position()))
|
|
19
|
+
except:
|
|
20
|
+
# pass
|
|
21
|
+
return ('free','relative') # if the object does not have a position assume it obeys free/relative positioning
|
|
22
|
+
|
|
23
|
+
def groupby_position(objects):
|
|
24
|
+
from batoolset.draw.shapes.txt2d import TAText2D
|
|
25
|
+
if isinstance(objects, TAText2D):
|
|
26
|
+
objects = [objects]
|
|
27
|
+
# Sort the objects based on their positions
|
|
28
|
+
sorted_objects = sorted(objects, key=sorting_key)
|
|
29
|
+
# Group the sorted objects based on their positions
|
|
30
|
+
grouped_objects = {key: list(group) for key, group in groupby(sorted_objects, key=sorting_key)}
|
|
31
|
+
return grouped_objects
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Position:
|
|
35
|
+
positions = {
|
|
36
|
+
'top': False,
|
|
37
|
+
'bottom': False,
|
|
38
|
+
'left': False,
|
|
39
|
+
'right': False,
|
|
40
|
+
'center_h': False,
|
|
41
|
+
'center_v': False
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
def __init__(self, position=None):
|
|
45
|
+
self.positions = copy.deepcopy(Position.positions)
|
|
46
|
+
if position is not None:
|
|
47
|
+
self.set_position(position)
|
|
48
|
+
|
|
49
|
+
def set_position(self, position):
|
|
50
|
+
for key in self.positions.keys(): # reset all positions
|
|
51
|
+
self.positions[key] = False
|
|
52
|
+
|
|
53
|
+
if not position:
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
position = position.lower()
|
|
57
|
+
# except:
|
|
58
|
+
# traceback.print_exc()
|
|
59
|
+
# print('position', position)
|
|
60
|
+
|
|
61
|
+
if 'top' in position:
|
|
62
|
+
self.positions['top'] = True
|
|
63
|
+
if 'bottom' in position:
|
|
64
|
+
self.positions['bottom'] = True
|
|
65
|
+
if 'left' in position:
|
|
66
|
+
self.positions['left'] = True
|
|
67
|
+
if 'right' in position:
|
|
68
|
+
self.positions['right'] = True
|
|
69
|
+
if 'center_h' in position:
|
|
70
|
+
self.positions['center_h'] = True
|
|
71
|
+
if 'center_v' in position:
|
|
72
|
+
self.positions['center_v'] = True
|
|
73
|
+
|
|
74
|
+
def get_position(self):
|
|
75
|
+
return {key: value for key, value in self.positions.items() if value}
|
|
76
|
+
|
|
77
|
+
def check_position(self, position):
|
|
78
|
+
if not position in self.positions:
|
|
79
|
+
return False
|
|
80
|
+
return self.positions[position]
|
|
81
|
+
|
|
82
|
+
def position_to_string(self):
|
|
83
|
+
out = ''
|
|
84
|
+
if self.positions['top']:
|
|
85
|
+
out += 'top '
|
|
86
|
+
if self.positions['bottom']:
|
|
87
|
+
out += 'bottom '
|
|
88
|
+
if self.positions['left']:
|
|
89
|
+
out += 'left '
|
|
90
|
+
if self.positions['right']:
|
|
91
|
+
out += 'right '
|
|
92
|
+
if self.positions['center_h']:
|
|
93
|
+
out += 'center_h '
|
|
94
|
+
if self.positions['center_v']:
|
|
95
|
+
out += 'center_v '
|
|
96
|
+
|
|
97
|
+
return out.strip()
|
|
98
|
+
|
|
99
|
+
def get_packing_orientation(self):
|
|
100
|
+
# try rescue packing mode from position
|
|
101
|
+
# if reference.position.get_position():
|
|
102
|
+
if self.check_position('top'):
|
|
103
|
+
return packing_modes[1]
|
|
104
|
+
elif self.check_position('bottom'):
|
|
105
|
+
return packing_modes[3]
|
|
106
|
+
# elif mode.check_position('left'):
|
|
107
|
+
# mode = packing_modes[0]
|
|
108
|
+
# elif mode.check_position('right'):
|
|
109
|
+
# mode = packing_modes[2]
|
|
110
|
+
# else:
|
|
111
|
+
# # logger.error('unknown positioning --> ignoring')
|
|
112
|
+
# print('unknown position ignoring')
|
|
113
|
+
|
|
114
|
+
def isEmpty(self):
|
|
115
|
+
for key, value in self.positions.items():
|
|
116
|
+
if value:
|
|
117
|
+
return False
|
|
118
|
+
return True
|
|
119
|
+
|
|
120
|
+
def __str__(self):
|
|
121
|
+
return self.position_to_string()
|
|
122
|
+
|
|
123
|
+
# very good --> maybe just slightly improve it and fix it --> it will be placed with repsect to the parent stuff
|
|
124
|
+
if __name__ == '__main__':
|
|
125
|
+
# Create a new Position object
|
|
126
|
+
p = Position()
|
|
127
|
+
print(p.get_position()) # --> empty
|
|
128
|
+
|
|
129
|
+
# Set the position
|
|
130
|
+
p.set_position('top left')
|
|
131
|
+
# Get the current position
|
|
132
|
+
print(p.get_position()) # Output: {'top': True, 'left': True}
|
|
133
|
+
|
|
134
|
+
p.set_position('TOp Left')
|
|
135
|
+
# Get the current position
|
|
136
|
+
print(p.get_position()) # Output: {'top': True, 'left': True}
|
|
137
|
+
|
|
138
|
+
p.set_position('Bottom Right')
|
|
139
|
+
# Get the current position
|
|
140
|
+
print(p.get_position()) # Output: {'top': True, 'left': True}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
print('pos to string', p.position_to_string())
|
|
144
|
+
|
|
145
|
+
print(p.check_position('top'))
|
|
146
|
+
print(p.check_position('right'))
|
|
147
|
+
print(p.check_position('bottom'))
|
|
148
|
+
|
|
149
|
+
p2 = Position()
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
print(p2.get_position())
|
|
154
|
+
|
|
155
|
+
print(p2.isEmpty())
|
|
156
|
+
print(p.isEmpty())
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
if False:
|
|
161
|
+
|
|
162
|
+
# List of objects with positions
|
|
163
|
+
objects = [
|
|
164
|
+
{'top': True, 'left': True},
|
|
165
|
+
{'bottom': True, 'right': True},
|
|
166
|
+
{'top': True, 'left': True},
|
|
167
|
+
{'bottom': True, 'left': True}
|
|
168
|
+
]
|
|
169
|
+
|
|
170
|
+
grouped_objects = groupby_position(objects)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
print(grouped_objects)
|
|
176
|
+
|
|
177
|
+
# Print the grouped objects
|
|
178
|
+
for position, objects_in_group in grouped_objects.items():
|
|
179
|
+
print(f"Position: {position}")
|
|
180
|
+
for obj in objects_in_group:
|
|
181
|
+
print(obj)
|
|
182
|
+
print()
|
|
183
|
+
|
|
File without changes
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
from batoolset.settings.global_settings import set_UI # set the UI to qtpy
|
|
2
|
+
set_UI()
|
|
3
|
+
import random
|
|
4
|
+
import sys
|
|
5
|
+
from qtpy.QtGui import QTransform,QPolygon
|
|
6
|
+
from qtpy.QtWidgets import QApplication, QWidget
|
|
7
|
+
from qtpy.QtGui import QPainter, QPen, QBrush, QColor
|
|
8
|
+
from qtpy.QtCore import Qt, QPointF, QRectF,QPoint
|
|
9
|
+
from batoolset.draw.shapes.polyline2d import PolyLine2D
|
|
10
|
+
from batoolset.draw.shapes.transform2D import get_centroid, get_points, Transform2D
|
|
11
|
+
|
|
12
|
+
def compute_translation_corrections(img1, minimal_return=True):
|
|
13
|
+
old_scale = img1.scale
|
|
14
|
+
img1.set_to_scale(1.)
|
|
15
|
+
|
|
16
|
+
parent_rect = QRectF(img1.getRect(raw=True))
|
|
17
|
+
parent_rect = QRectF(0, 0, parent_rect.width(), parent_rect.height())
|
|
18
|
+
|
|
19
|
+
theta = img1.theta
|
|
20
|
+
if not theta:
|
|
21
|
+
theta=0
|
|
22
|
+
crop_left = img1.crop_left
|
|
23
|
+
crop_right = img1.crop_right
|
|
24
|
+
crop_top = img1.crop_top
|
|
25
|
+
crop_bottom = img1.crop_bottom
|
|
26
|
+
if not crop_left:
|
|
27
|
+
crop_left=0
|
|
28
|
+
if not crop_right:
|
|
29
|
+
crop_right=0
|
|
30
|
+
if not crop_top:
|
|
31
|
+
crop_top=0
|
|
32
|
+
if not crop_bottom:
|
|
33
|
+
crop_bottom=0
|
|
34
|
+
|
|
35
|
+
center_parent = parent_rect.center()
|
|
36
|
+
transform = QTransform()
|
|
37
|
+
transform.translate(-center_parent.x(), -center_parent.y())
|
|
38
|
+
transform.rotate(theta)
|
|
39
|
+
transform.translate(center_parent.x(), center_parent.y())
|
|
40
|
+
rotated_rect = transform.mapToPolygon(parent_rect.toRect()) # this is the center versio n
|
|
41
|
+
rotated_rect_bounds = transform.mapRect(parent_rect)
|
|
42
|
+
trans = parent_rect.center() - rotated_rect_bounds.center() # this is the center version
|
|
43
|
+
rotated_rect_bounds.translate(trans)
|
|
44
|
+
rotated_rect_before_trans = QPolygon(rotated_rect)
|
|
45
|
+
rotated_rect.translate(int(trans.x()), int(trans.y())) # --> error --> this stuff is not at the right place
|
|
46
|
+
crop_rect = QRectF(rotated_rect_bounds.x() + crop_left, rotated_rect_bounds.y() + crop_top,
|
|
47
|
+
rotated_rect_bounds.width() - crop_right - crop_left,
|
|
48
|
+
rotated_rect_bounds.height() - crop_top - crop_bottom)
|
|
49
|
+
rect = crop_rect
|
|
50
|
+
centroid_of_crop = get_centroid(get_points(rect))
|
|
51
|
+
|
|
52
|
+
center_before_reg = get_centroid(get_points(rotated_rect_before_trans))
|
|
53
|
+
rotated_rect_before_trans.translate(-int(center_before_reg[0] - centroid_of_crop[0]),
|
|
54
|
+
-int(center_before_reg[1] - centroid_of_crop[1]))
|
|
55
|
+
|
|
56
|
+
fixing_error_trans = img1.getRect(all=True).center() - crop_rect.center()
|
|
57
|
+
extra_fix = QPointF(
|
|
58
|
+
rotated_rect_before_trans.boundingRect().center() - rotated_rect.boundingRect().center()) # now it is perfectly aligned to the light cyan rect -−> how cna I realign it now to the cyan rect
|
|
59
|
+
fixing_error_trans += extra_fix
|
|
60
|
+
extra_user_translation = (fixing_error_trans.x(), fixing_error_trans.y())
|
|
61
|
+
|
|
62
|
+
img1.set_to_scale(old_scale)
|
|
63
|
+
|
|
64
|
+
# bug fix if image is not at 0,0, remove extra useless translation
|
|
65
|
+
extra_user_translation = (extra_user_translation[0]-img1.x(), extra_user_translation[1]-img1.y())
|
|
66
|
+
|
|
67
|
+
if minimal_return:
|
|
68
|
+
return extra_user_translation,rotated_rect.boundingRect().center() - rotated_rect_before_trans.boundingRect().center()
|
|
69
|
+
else:
|
|
70
|
+
return centroid_of_crop,center_parent, rotated_rect_before_trans, crop_rect, parent_rect, rotated_rect_bounds, rotated_rect, extra_user_translation,rotated_rect.boundingRect().center()-rotated_rect_before_trans.boundingRect().center()
|
|
71
|
+
#
|
|
72
|
+
# class AutomaticDrawingOfRegistrationRect(QWidget):
|
|
73
|
+
# def __init__(self):
|
|
74
|
+
# super().__init__()
|
|
75
|
+
#
|
|
76
|
+
# self.MODE_CHECK = True # I fTrue uses the default mode
|
|
77
|
+
#
|
|
78
|
+
# self.theta = random.randint(-359, 359)
|
|
79
|
+
# self.theta = 42
|
|
80
|
+
# self.theta = 0
|
|
81
|
+
#
|
|
82
|
+
# lines = [
|
|
83
|
+
# (0, 0, 0, 0),
|
|
84
|
+
# (30, 40, 60, 80),
|
|
85
|
+
# (90, 10, 33, 16),
|
|
86
|
+
# (60, 30, 0, 0), # this one seems buggy
|
|
87
|
+
# (60, 0, 0, 0),
|
|
88
|
+
# (90, 0, 0, 0),
|
|
89
|
+
# (0, 60, 0, 0),
|
|
90
|
+
# (0, 90, 0, 0),
|
|
91
|
+
# (60, 60, 0, 0),
|
|
92
|
+
# (60, 60, 40, 40),
|
|
93
|
+
# (0, 0, 40, 40),
|
|
94
|
+
# (0, 0, 0, 40),
|
|
95
|
+
# (0, 0, 0, 90),
|
|
96
|
+
# (0, 0, 40, 0),
|
|
97
|
+
# (0, 0, 90, 0),
|
|
98
|
+
# (60, 0, 40, 0),
|
|
99
|
+
# (60, 0, 0, 40),
|
|
100
|
+
# (0, 60, 0, 40),
|
|
101
|
+
# (0, 60, 40, 0),
|
|
102
|
+
# (0, 60, 40, 30),
|
|
103
|
+
# (60, 0, 40, 30),
|
|
104
|
+
# (60, 40, 0, 30),
|
|
105
|
+
# (60, 40, 50, 0),
|
|
106
|
+
# (30, 70, 10, 0)
|
|
107
|
+
# ]
|
|
108
|
+
#
|
|
109
|
+
# # Randomly select a line and execute it
|
|
110
|
+
# self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = random.choice(lines)
|
|
111
|
+
#
|
|
112
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 0, 0, 0, 0
|
|
113
|
+
# self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 30, 40, 60, 80
|
|
114
|
+
# self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 60, 30, 0, 0
|
|
115
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 90, 10, 33, 16
|
|
116
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 60, 0, 0, 0
|
|
117
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 90, 0, 0, 0
|
|
118
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 0, 60, 0, 0
|
|
119
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 0, 90, 0, 0
|
|
120
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 60, 60, 0, 0
|
|
121
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 60, 60, 40, 40
|
|
122
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 0, 0, 40, 40
|
|
123
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 0, 0, 0, 40
|
|
124
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 0, 0, 0, 90
|
|
125
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 0, 0, 40, 0
|
|
126
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 0, 0, 90, 0
|
|
127
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 60, 0, 40, 0
|
|
128
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 60, 0, 0, 40
|
|
129
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 0, 60, 0, 40
|
|
130
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 0, 60, 40, 0
|
|
131
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 0, 60, 40, 30
|
|
132
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 60, 0, 40, 30
|
|
133
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 60, 40, 0, 30
|
|
134
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 60, 40, 50, 0
|
|
135
|
+
# # self.crop_left, self.crop_right, self.crop_top, self.crop_bottom = 30, 70, 10, 0
|
|
136
|
+
#
|
|
137
|
+
# from pyfigures.gui.keep_tst_images_for_pzf import get_complex_tst_image
|
|
138
|
+
# img1 = get_complex_tst_image()
|
|
139
|
+
# img1.set_rotation(self.theta)
|
|
140
|
+
# img1.crop(self.crop_left, self.crop_right, self.crop_top, self.crop_bottom)
|
|
141
|
+
# # img1.set_to_scale(1) # make sure it is full size
|
|
142
|
+
# self.img = img1
|
|
143
|
+
#
|
|
144
|
+
# # if there is scaling --> there is an error --> try to see why that is
|
|
145
|
+
# # self.img.set_to_scale(1./0.3)
|
|
146
|
+
#
|
|
147
|
+
# print(self.img.scale)
|
|
148
|
+
# self.img.scale=1 # apparently the bug is there
|
|
149
|
+
# # self.img.scale=1/0.3 # apparently the bug is there # ok --> now scale is finally supported --> very good
|
|
150
|
+
# # self.img.scale=2
|
|
151
|
+
#
|
|
152
|
+
# # test of all
|
|
153
|
+
#
|
|
154
|
+
# self.centroid_of_crop, self.center_parent, self.rotated_rect_before_trans, self.crop_rect, self.parent_rect, self.rotated_rect_bounds, self.rotated_rect, extra_user_translation, self.extra_translation_at_painter = compute_translation_corrections(img1, minimal_return=False)
|
|
155
|
+
#
|
|
156
|
+
# if not self.MODE_CHECK:
|
|
157
|
+
# self.img.extra_user_translation = extra_user_translation
|
|
158
|
+
# else:
|
|
159
|
+
# self.img.extra_user_translation = (0,0)
|
|
160
|
+
#
|
|
161
|
+
# self.rect = self.crop_rect
|
|
162
|
+
#
|
|
163
|
+
# print('extra_user_translation', extra_user_translation)
|
|
164
|
+
# print('extra_translation_at_painter', self.extra_translation_at_painter)
|
|
165
|
+
# # print('fixing_error_trans', self.fixing_error_trans)
|
|
166
|
+
#
|
|
167
|
+
# self.line_length = 10 # pixels
|
|
168
|
+
# self.colors = [QColor(Qt.red), QColor(Qt.green), QColor(Qt.blue), QColor(Qt.yellow)]
|
|
169
|
+
#
|
|
170
|
+
# self.center_after_reg = get_centroid(get_points(self.rotated_rect_before_trans))
|
|
171
|
+
#
|
|
172
|
+
# points_of_unrotated_rect = get_points(self.rect)
|
|
173
|
+
# trafo2D = Transform2D()
|
|
174
|
+
# trafo2D.translate(self.center_parent.x(), self.center_parent.y())
|
|
175
|
+
# trafo2D.rotate(-self.theta)
|
|
176
|
+
# trafo2D.translate(-self.center_parent.x(), -self.center_parent.y())
|
|
177
|
+
#
|
|
178
|
+
# # this will give me the rect to plot on the parent -−> quite easy
|
|
179
|
+
# rotated_back_points = trafo2D.apply(points_of_unrotated_rect)
|
|
180
|
+
# self.fixed_center = get_centroid(rotated_back_points)
|
|
181
|
+
#
|
|
182
|
+
# self.setMinimumSize(800,600)
|
|
183
|
+
# self.update()
|
|
184
|
+
#
|
|
185
|
+
#
|
|
186
|
+
# def draw_alignment_rect(self, painter):
|
|
187
|
+
# painter.setPen(QColor(0, 0, 0))
|
|
188
|
+
#
|
|
189
|
+
# # Draw the crop values as text
|
|
190
|
+
# painter.drawText(10, 20, f"Crop Left: {self.crop_left}")
|
|
191
|
+
# painter.drawText(10, 40, f"Crop Right: {self.crop_right}")
|
|
192
|
+
# painter.drawText(10, 60, f"Crop Top: {self.crop_top}")
|
|
193
|
+
# painter.drawText(10, 80, f"Crop Bottom: {self.crop_bottom}")
|
|
194
|
+
# painter.drawText(10, 100, f"Angle: {self.theta }")
|
|
195
|
+
#
|
|
196
|
+
# painter.translate(256, 256) # just to better visualize and understand all !! -> TODO
|
|
197
|
+
#
|
|
198
|
+
# if True:
|
|
199
|
+
# random_number = random.uniform(0.1, 3.0)
|
|
200
|
+
# painter.scale(random_number,random_number) # ça marche et c'est scale insensitive --> TODO à fixer
|
|
201
|
+
#
|
|
202
|
+
#
|
|
203
|
+
#
|
|
204
|
+
# if True:
|
|
205
|
+
# painter.save()
|
|
206
|
+
# # if not (self.crop_left and self.crop_right and self.crop_top and self.crop_bottom):
|
|
207
|
+
# # if False:
|
|
208
|
+
# if True:
|
|
209
|
+
# painter.translate((self.crop_rect.center() - self.img.getRect(all=True).center())/self.img.scale) # very good -> this is sufficient to align the center to that
|
|
210
|
+
# # this is just to center the image this stuff is in fact largely usless!!!
|
|
211
|
+
#
|
|
212
|
+
# # pass
|
|
213
|
+
# # painter.translate(self.center_after_reg[0]- self.img.getRect(all=True).center().x(),self.center_after_reg[1]- self.img.getRect(all=True).center().y()) # very good -> this is sufficient to align the center to that
|
|
214
|
+
# # painter.translate(self.center_after_reg[0]- self.img.getRect(all=True).center().x(),self.center_after_reg[1]- self.img.getRect(all=True).center().y()) # very good -> this is sufficient to align the center to that
|
|
215
|
+
# # painter.translate(self.rotated_rect.boundingRect().center().x()-self.img.getRect(all=True).center().x(),self.rotated_rect.boundingRect().center().y()-self.img.getRect(all=True).center().y()) # very good -> this is sufficient to align the center to that
|
|
216
|
+
# # rotated center centered on that
|
|
217
|
+
# self.img.draw_bg(painter, restore_painter_in_the_end=True)
|
|
218
|
+
#
|
|
219
|
+
# # this is the really important stuff and again it should be scaled
|
|
220
|
+
# # painter.translate(self.rotated_rect.boundingRect().center()-self.rotated_rect_before_trans.boundingRect().center()) # ça marche is je met le truc ici --> par contre est ce que je controle la position ???
|
|
221
|
+
# if not self.MODE_CHECK:
|
|
222
|
+
# # if True:
|
|
223
|
+
# painter.translate(self.extra_translation_at_painter/self.img.scale) # ça marche is je met le truc ici --> par contre est ce que je controle la position ???
|
|
224
|
+
#
|
|
225
|
+
# self.img.draw_annotations(painter, restore_painter_in_the_end=False)
|
|
226
|
+
# painter.restore()
|
|
227
|
+
#
|
|
228
|
+
# # Reset the clipping region
|
|
229
|
+
# # painter.setClipping(False)
|
|
230
|
+
#
|
|
231
|
+
# shapes_drawn = []
|
|
232
|
+
#
|
|
233
|
+
# pen = QPen(Qt.lightGray, 6)
|
|
234
|
+
# painter.setPen(pen)
|
|
235
|
+
# # Draw the rectangle
|
|
236
|
+
# painter.drawRect(self.parent_rect)
|
|
237
|
+
# pen.setWidthF(24)
|
|
238
|
+
# painter.setPen(pen)
|
|
239
|
+
# painter.drawPoint(self.parent_rect.center()) # ok
|
|
240
|
+
#
|
|
241
|
+
# pen = QPen(Qt.yellow, 6)
|
|
242
|
+
# painter.setPen(pen)
|
|
243
|
+
# # Draw the rectangle
|
|
244
|
+
# painter.drawRect(self.rotated_rect_bounds)
|
|
245
|
+
# pen.setWidthF(12)
|
|
246
|
+
# painter.setPen(pen)
|
|
247
|
+
# painter.drawPoint(self.rotated_rect_bounds.center()) # ok
|
|
248
|
+
#
|
|
249
|
+
# pen = QPen(Qt.cyan,6)
|
|
250
|
+
# painter.setPen(pen)
|
|
251
|
+
# painter.drawPolygon(self.rotated_rect)
|
|
252
|
+
# painter.drawPoint(self.rotated_rect.boundingRect().center())
|
|
253
|
+
#
|
|
254
|
+
# # pen = QPen(QColor(224, 128, 255), 6) # lighcyan
|
|
255
|
+
# pen = QPen(QColor(255, 0, 0), 1) # lighcyan
|
|
256
|
+
# painter.setPen(pen)
|
|
257
|
+
# painter.drawPolygon(self.rotated_rect_before_trans)
|
|
258
|
+
# pen.setWidthF(12)
|
|
259
|
+
# painter.setPen(pen)
|
|
260
|
+
# painter.drawPoint(
|
|
261
|
+
# self.rotated_rect_before_trans.boundingRect().center()) # this is aligned with the the centroid of crop probably by construction
|
|
262
|
+
#
|
|
263
|
+
# # painter.save()
|
|
264
|
+
# # painter.translate(-center_parent.x(), -center_parent.y())
|
|
265
|
+
# # painter.rotate(self.theta)
|
|
266
|
+
# # painter.translate(center_parent.x(), center_parent.y())
|
|
267
|
+
#
|
|
268
|
+
# pen = QPen(Qt.darkGray, 6)
|
|
269
|
+
# painter.setPen(pen)
|
|
270
|
+
# # Draw the rectangle
|
|
271
|
+
# painter.drawRect(self.rect)
|
|
272
|
+
# painter.drawPoint(int(self.centroid_of_crop[0]), int(self.centroid_of_crop[1])) # ok
|
|
273
|
+
#
|
|
274
|
+
# # maybe get the center of the rotated back shit
|
|
275
|
+
#
|
|
276
|
+
# if True:
|
|
277
|
+
# # this belongs to the unrotated rect that I never plotted
|
|
278
|
+
# pen = QPen(Qt.red, 3)
|
|
279
|
+
# painter.setPen(pen)
|
|
280
|
+
# painter.drawPoint(int(self.fixed_center[0]),int(self.fixed_center[1])) # ok
|
|
281
|
+
#
|
|
282
|
+
# # now put the extra correction
|
|
283
|
+
# # maybe it is one of these centroids that I should use
|
|
284
|
+
#
|
|
285
|
+
# # painter.restore()
|
|
286
|
+
#
|
|
287
|
+
# # Draw two orthogonal lines at each corner with unique colors
|
|
288
|
+
# corners = [self.rect.topLeft(), self.rect.topRight(), self.rect.bottomLeft(), self.rect.bottomRight()]
|
|
289
|
+
# for i, point in enumerate(corners):
|
|
290
|
+
# x, y = point.x(), point.y()
|
|
291
|
+
# sign_x, sign_y = 1, 1
|
|
292
|
+
# if i in [1, 3]:
|
|
293
|
+
# sign_x = -1
|
|
294
|
+
# if i in [2, 3]:
|
|
295
|
+
# sign_y = -1
|
|
296
|
+
# painter.setPen(QPen(self.colors[i], 2))
|
|
297
|
+
# painter.drawLine(point, QPointF(x + self.line_length * sign_x, y))
|
|
298
|
+
# painter.drawLine(point, QPointF(x, y + self.line_length * sign_y))
|
|
299
|
+
# # test = PolyLine2D(*[x + self.line_length * sign_x, x,y, x,y, x , y + self.line_length * sign_y])
|
|
300
|
+
# corner = PolyLine2D(x + self.line_length * sign_x, y, x, y, x, y, x, y + self.line_length * sign_y, stroke=1,
|
|
301
|
+
# color=self.colors[i].toRgb())
|
|
302
|
+
# # corner.draw(painter)
|
|
303
|
+
# shapes_drawn.append(corner)
|
|
304
|
+
#
|
|
305
|
+
# # print(test.count())
|
|
306
|
+
#
|
|
307
|
+
# # Draw a cross at the center
|
|
308
|
+
# center = self.rect.center()
|
|
309
|
+
# pen = QPen(QColor(Qt.magenta), 2)
|
|
310
|
+
# painter.setPen(pen)
|
|
311
|
+
# painter.drawLine(QPointF(center.x() - self.line_length, center.y()),
|
|
312
|
+
# QPointF(center.x() + self.line_length, center.y()))
|
|
313
|
+
# painter.drawLine(QPointF(center.x(), center.y() - self.line_length),
|
|
314
|
+
# QPointF(center.x(), center.y() + self.line_length))
|
|
315
|
+
# horiz = PolyLine2D(center.x() - self.line_length, center.y(), center.x() + self.line_length, center.y(),
|
|
316
|
+
# stroke=1,
|
|
317
|
+
# color=QColor(Qt.magenta).toRgb())
|
|
318
|
+
# vert = PolyLine2D(center.x(), center.y() - self.line_length, center.x(), center.y() + self.line_length,
|
|
319
|
+
# stroke=1,
|
|
320
|
+
# color=QColor(Qt.magenta).toRgb())
|
|
321
|
+
# # horiz.draw(painter)
|
|
322
|
+
# # vert.draw(painter)
|
|
323
|
+
# shapes_drawn.append(horiz)
|
|
324
|
+
# shapes_drawn.append(vert)
|
|
325
|
+
# return shapes_drawn
|
|
326
|
+
#
|
|
327
|
+
# def paintEvent(self, event):
|
|
328
|
+
# painter = QPainter(self)
|
|
329
|
+
#
|
|
330
|
+
# shapes_drawn = self.draw_alignment_rect(painter)
|
|
331
|
+
#
|
|
332
|
+
# # Now I could try to really map these shapes on the real image!!!
|
|
333
|
+
#
|
|
334
|
+
# # print(shapes_drawn)
|
|
335
|
+
# painter.end()
|
|
336
|
+
# # the shapes and te lines are now ok --> I can then use them to register the fake image and compute the messed up translation --> TODO
|
|
337
|
+
#
|
|
338
|
+
# # convert this also to a polyline line object so that I can draw it!!!
|
|
339
|
+
# # see how I can do that
|
|
340
|
+
#
|
|
341
|
+
# if __name__ == '__main__':
|
|
342
|
+
# app = QApplication(sys.argv)
|
|
343
|
+
# widget = AutomaticDrawingOfRegistrationRect()
|
|
344
|
+
# widget.resize(640, 480)
|
|
345
|
+
# widget.show()
|
|
346
|
+
# sys.exit(app.exec_())
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
from batoolset.draw.shapes.ellipse2d import *
|
|
2
|
+
from batoolset.tools.logger import TA_logger
|
|
3
|
+
|
|
4
|
+
logger = TA_logger()
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Circle2D(Ellipse2D):
|
|
8
|
+
|
|
9
|
+
def __init__(self, *args,x=0, y=0, width=0, color=0xFFFFFF, fill_color=None, opacity=1., stroke=0.65,line_style=None, __version__=1.0, **kwargs):
|
|
10
|
+
# print('args here',args)
|
|
11
|
+
if len(args) == 3:
|
|
12
|
+
super(Circle2D, self).__init__(*args, args[-1])
|
|
13
|
+
elif len(args) == 4:
|
|
14
|
+
logger.error("too many values, cirle only has, x,y and width")
|
|
15
|
+
else:
|
|
16
|
+
if args:
|
|
17
|
+
super(Circle2D, self).__init__(*args) # create empty circle
|
|
18
|
+
else:
|
|
19
|
+
super(Circle2D, self).__init__(x,y,width, width) # create empty circle
|
|
20
|
+
self.setRect(self.rect())
|
|
21
|
+
self.color = color
|
|
22
|
+
self.fill_color = fill_color
|
|
23
|
+
self.stroke = stroke
|
|
24
|
+
self.opacity = opacity
|
|
25
|
+
self.line_style = line_style
|
|
26
|
+
self.__version__ = __version__
|
|
27
|
+
# rotation
|
|
28
|
+
# self.theta = theta
|
|
29
|
+
|
|
30
|
+
def add(self, *args): # this is required for drawing a cicrle otherwise it becomes as ellipse...
|
|
31
|
+
p1 = args[0]
|
|
32
|
+
p2 = args[1]
|
|
33
|
+
|
|
34
|
+
rect = self.rect()
|
|
35
|
+
|
|
36
|
+
x = p2.x()
|
|
37
|
+
y = p2.y()
|
|
38
|
+
x2 = p1.x()
|
|
39
|
+
y2 = p1.y()
|
|
40
|
+
if p1.x() < p2.x():
|
|
41
|
+
x = p1.x()
|
|
42
|
+
x2 = p2.x()
|
|
43
|
+
if p1.y() < p2.y():
|
|
44
|
+
y = p1.y()
|
|
45
|
+
y2 = p2.y()
|
|
46
|
+
w = abs(x - x2)
|
|
47
|
+
h = abs(y - y2)
|
|
48
|
+
if w < h:
|
|
49
|
+
rect.setWidth(h)
|
|
50
|
+
rect.setHeight(h)
|
|
51
|
+
else:
|
|
52
|
+
rect.setWidth(w)
|
|
53
|
+
rect.setHeight(w)
|
|
54
|
+
|
|
55
|
+
rect.setX(x)
|
|
56
|
+
rect.setY(y)
|
|
57
|
+
|
|
58
|
+
self.setRect(rect)
|
|
59
|
+
self.isSet = True
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if __name__ == '__main__':
|
|
63
|
+
test = Circle2D(0, 0, 100)
|
|
64
|
+
# print(test.x(), test.y(), test.width(), test.height())
|
|
65
|
+
print(test.contains(QPointF(50, 50)))
|
|
66
|
+
print(test.contains(QPointF(15, 15)))
|
|
67
|
+
print(test.contains(QPointF(-1, -1)))
|
|
68
|
+
print(test.contains(QPointF(0, 0)))
|
|
69
|
+
print(test.contains(QPointF(100, 100)))
|
|
70
|
+
print(test.contains(QPointF(100, 100.1)))
|
|
71
|
+
print(test.x())
|
|
72
|
+
print(test.y())
|
|
73
|
+
print(test.translate(QPoint(10, 10)))
|
|
74
|
+
print(test.x())
|
|
75
|
+
print(test.y())
|
|
76
|
+
|
|
77
|
+
# p1 = test.p1()
|
|
78
|
+
# print(p1.x(), p1.y())
|
|
79
|
+
# p2 = test.p2()
|
|
80
|
+
# print(p2.x(), p2.y())
|
|
81
|
+
# print(test.arrow)
|
|
82
|
+
# print(test.length()) # sqrt 2 --> 141
|
|
83
|
+
# # if it's an arrow I can add easily all the stuff I need
|
|
84
|
+
#
|
|
85
|
+
# test = Rect2D(0, 0, 1, 1)
|
|
86
|
+
# p1 = test.p1()
|
|
87
|
+
# print(p1.x(), p1.y())
|
|
88
|
+
# p2 = test.p2()
|
|
89
|
+
# print(p2.x(), p2.y())
|
|
90
|
+
# print(test.arrow)
|
|
91
|
+
# import math
|
|
92
|
+
# print(test.length() == math.sqrt(2)) # sqrt 2
|
|
93
|
+
#
|
|
94
|
+
# test2 = Rect2D()
|
|
95
|
+
# p1 = test2.p1()
|
|
96
|
+
# print(p1.x(), p1.y())
|
|
97
|
+
# p2 = test2.p2()
|
|
98
|
+
# print(p2.x(), p2.y())
|
|
99
|
+
# print(test2.arrow)
|