Skip to content

Commit 395405f

Browse files
author
arch
committed
apply offset befor calc roll score (untested)
1 parent 69f7622 commit 395405f

File tree

2 files changed

+67
-15
lines changed

2 files changed

+67
-15
lines changed

funscript_editor/algorithms/funscriptgenerator.py

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,48 @@ def interpolate_bboxes(self, bboxes :dict) -> dict:
160160
return interpolated_bboxes
161161

162162

163+
@staticmethod
164+
def clamp(val: float, min_value: float, max_value: float) -> float:
165+
""" limit a value in a given range
166+
167+
Args:
168+
val (float): input value
169+
min_value (float): min allowed value
170+
max_value (float): max allowed value
171+
172+
Returns:
173+
float: clamp value
174+
"""
175+
return max(min(val, max_value), min_value)
176+
177+
178+
def get_dick_pos(self, max_distance_frame_num: int) -> dict:
179+
""" Get Start and End points of the dick
180+
181+
Args:
182+
max_distance_frame_num (int): absolute frame number with max tracker distance
183+
184+
Returns:
185+
dict: dick points
186+
"""
187+
max_distance_frame = FFmpegStream.get_frame(self.params.video_path, max_distance_frame_num)
188+
max_distance_frame = FFmpegStream.get_projection(max_distance_frame, self.projection_config)
189+
frame_h, frame_w = max_distance_frame.shape[:2]
190+
center_line = self.ui.line_selector(max_distance_frame, "draw line on center of dick")
191+
192+
# last idx: 0 = x, 1 = y
193+
dick_pos = { 'w': center_line[1], 'm': center_line[0] } \
194+
if center_line[0][0] > center_line[1][0] \
195+
else { 'w': center_line[0], 'm': center_line[1] }
196+
197+
# TODO: dividor is an hyperparameter
198+
dx = (dick_pos['m'][0] - dick_pos['w'][0]) / 8
199+
dy = (dick_pos['m'][1] - dick_pos['w'][1]) / 8
200+
return {
201+
'w': (self.clamp(dick_pos['w'][0] - dx, 0, frame_w-1), self.clamp(dick_pos['w'][1] - dy, 0, frame_h-1)),
202+
'm': (self.clamp(dick_pos['m'][0] + dx, 0, frame_w-1), self.clamp(dick_pos['m'][1] + dy, 0, frame_h-1))
203+
}
204+
163205

164206
def calculate_score(self, bboxes) -> None:
165207
""" Calculate the score for the predicted tracking boxes
@@ -176,6 +218,9 @@ def calculate_score(self, bboxes) -> None:
176218
'distance': [np.array([]) for _ in range(self.params.number_of_trackers)],
177219
'roll': [[] for _ in range(self.params.number_of_trackers)]
178220
}
221+
222+
dick_pos = None
223+
179224
self.logger.info("Calculate score for %d Tracker(s)", self.params.number_of_trackers)
180225
for tracker_number in range(self.params.number_of_trackers):
181226
woman_center = [self.get_center(item) for item in bboxes['Woman'][tracker_number]]
@@ -189,9 +234,18 @@ def calculate_score(self, bboxes) -> None:
189234
score['distance'][tracker_number] = np.array([np.sqrt(np.sum((np.array(m) - np.array(w)) ** 2, axis=0)) \
190235
for w, m in zip(woman_center, men_center)])
191236

237+
if dick_pos is None:
238+
max_distance_frame_num = np.argmax(np.array([abs(x) for x in score['distance'][tracker_number]])) + self.params.start_frame
239+
dick_pos = self.get_dick_pos(max_distance_frame_num)
240+
dick_pos['idx'] = max_distance_frame_num - self.params.start_frame
241+
242+
roll_woman_offset = (dick_pos['w'][0] - woman_center[dick_pos['idx']][0], dick_pos['w'][1] - woman_center[dick_pos['idx']][1])
243+
roll_men_offset = (dick_pos['m'][0] - woman_center[dick_pos['idx']][0], dick_pos['m'][1] - woman_center[dick_pos['idx']][1])
244+
self.logger.info('use roll offset w = %s, m = %s', str(roll_woman_offset), str(roll_men_offset))
245+
192246
for i in range( min(( len(men_center), len(woman_center) )) ):
193-
x = woman_center[i][0] - men_center[i][0]
194-
y = men_center[i][1] - woman_center[i][1]
247+
x = woman_center[i][0] + roll_woman_offset[0] - (men_center[i][0] + roll_men_offset[0])
248+
y = men_center[i][1] + roll_men_offset[1] - (woman_center[i][1] + roll_woman_offset[1])
195249
if x >= 0 and y >= 0:
196250
score['roll'][tracker_number].append(np.arctan(np.array(y / max((10e-3, x)))))
197251
elif x >= 0 and y < 0:
@@ -270,15 +324,6 @@ def scale_score(self, status: str, metric : str = 'y') -> None:
270324
imgMin = FFmpegStream.get_projection(imgMin, self.projection_config)
271325
imgMax = FFmpegStream.get_projection(imgMax, self.projection_config)
272326

273-
if metric == 'roll':
274-
max_distance_frame_num = np.argmax(np.array([abs(x) for x in self.score['distance']])) + self.params.start_frame
275-
max_distance_frame = FFmpegStream.get_frame(self.params.video_path, max_distance_frame_num)
276-
max_distance_frame = FFmpegStream.get_projection(max_distance_frame, self.projection_config)
277-
center_line = self.ui.line_selector(max_distance_frame, "draw line on center of dick")
278-
max_distance_roll_score = self.score['roll'][max_distance_frame_num - self.params.start_frame]
279-
print('center line', center_line)
280-
# TODO calc angel of line and apply max_distance_roll_score to get real center offset and appl offset to all items in roll score
281-
282327
min_tracking_points = self.get_tracking_points_by_frame_number(min_frame - self.params.start_frame)
283328
max_tracking_points = self.get_tracking_points_by_frame_number(max_frame - self.params.start_frame)
284329

@@ -290,7 +335,6 @@ def scale_score(self, status: str, metric : str = 'y') -> None:
290335

291336
# print('min_tracking_points', min_tracking_points, 'max_tracking_points', max_tracking_points)
292337

293-
294338
(desired_min, desired_max) = self.ui.min_max_selector(
295339
image_min = imgMin,
296340
image_max = imgMax,
@@ -307,7 +351,7 @@ def scale_score(self, status: str, metric : str = 'y') -> None:
307351

308352
self.logger.info("Scale score %s to user input", metric)
309353

310-
if False and metric == 'roll':
354+
if metric == 'roll':
311355
self.score[metric] = Signal.scale_with_center(self.score[metric], desired_min, desired_max, 50)
312356
else:
313357
self.score[metric] = Signal.scale(self.score[metric], desired_min, desired_max)

funscript_editor/ui/opencvui.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ def play_beep():
507507

508508
def line_selector(self,
509509
image: np.ndarray,
510-
txt: str):
510+
txt: str) -> list:
511511
""" Line Selector Widget
512512
513513
Args:
@@ -517,19 +517,27 @@ def line_selector(self,
517517
Returns:
518518
list: start and endpoint of line
519519
"""
520-
521520
line_widget = DrawSingleLineWidget(image, self.window_name, self.monitor_preview_scaling)
521+
note = ""
522522
while True:
523523
self.set_background_image(line_widget.show_image(), copy_image=False)
524524
self.print_text(txt)
525525
self.print_text("Press 'space' to continue")
526+
if len(note) > 0:
527+
self.print_text(note)
528+
526529
ret = self.show(5)
527530

528531
if self.was_any_accept_key_pressed() or any(ret == x for x in [ord(' '), 13]):
529532
result = line_widget.get_result()
530533
if result[0] is not None and result[1] is not None:
531534
if abs(result[0][0] - result[1][0]) + abs(result[0][1] - result[1][1]) > 10:
535+
self.show_loading_screen()
532536
return result
537+
else:
538+
note = "ERROR: Invalid selection"
539+
else:
540+
note = "ERROR: Missing Input"
533541

534542

535543
def min_max_selector(self,

0 commit comments

Comments
 (0)