Skip to content

Commit fadaddb

Browse files
authored
Merge pull request #16 from airpocket-soundman/main
add AlphaBlend node
2 parents b6ca13e + 58bd8c4 commit fadaddb

File tree

4 files changed

+401
-2
lines changed

4 files changed

+401
-2
lines changed

main.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,26 @@ def main():
127127
editor_width = opencv_setting_dict['editor_width']
128128
editor_height = opencv_setting_dict['editor_height']
129129

130+
# Serial接続デバイスチェック
131+
serial_device_no_list = []
132+
serial_connection_list = []
133+
use_serial = opencv_setting_dict['use_serial']
134+
if use_serial == True:
135+
import serial
136+
try:
137+
from .node_editor.util import check_serial_connection
138+
except:
139+
from node_editor.util import check_serial_connection
140+
print('**** Check Serial Device Connection ********')
141+
serial_device_no_list = check_serial_connection()
142+
for serial_device_no in serial_device_no_list:
143+
ser = serial.Serial(serial_device_no,115200)
144+
serial_connection_list.append(ser)
145+
146+
# Serial接続デバイス設定保持
147+
opencv_setting_dict['serial_device_no_list'] = serial_device_no_list
148+
opencv_setting_dict['serial_connection_list'] = serial_connection_list
149+
130150
print('**** DearPyGui Setup ********')
131151
dpg.create_context()
132152
dpg.setup_dearpygui()
Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
import time
4+
import re
5+
import cv2
6+
import numpy as np
7+
import dearpygui.dearpygui as dpg
8+
9+
from node_editor.util import dpg_get_value, dpg_set_value
10+
11+
from node.node_abc import DpgNodeABC
12+
from node_editor.util import convert_cv_to_dpg
13+
from node.draw_node.draw_util.draw_util import draw_info
14+
15+
def image_process(image1, image2, alpha_val, beta_val, gamma_val):
16+
image1_height, image1_width = image1.shape[:2]
17+
image2 = cv2.resize(image2, (image1_width, image1_height))
18+
image = cv2.addWeighted(image1, alpha_val, image2, beta_val, gamma_val)
19+
return image
20+
21+
def create_image_dict(
22+
slot_num,
23+
connection_info_src_dict,
24+
node_image_dict,
25+
node_result_dict,
26+
image_node_name,
27+
resize_width,
28+
resize_height,
29+
draw_info_on_result,
30+
):
31+
frame_exist_flag = False
32+
33+
# 初期化用黒画像
34+
black_image = np.zeros((resize_height, resize_width, 3)).astype(np.uint8)
35+
36+
frame_dict = {}
37+
for index in range(slot_num - 1, -1, -1):
38+
node_id_name = connection_info_src_dict.get(index, None)
39+
frame = copy.deepcopy(node_image_dict.get(node_id_name, None))
40+
if frame is not None:
41+
if draw_info_on_result:
42+
node_result = node_result_dict[node_id_name]
43+
image_node_name = node_id_name.split(':')[1]
44+
frame = draw_info(image_node_name, node_result, frame)
45+
resize_frame = cv2.resize(frame, (resize_width, resize_height))
46+
frame_dict[slot_num - index - 1] = copy.deepcopy(resize_frame)
47+
48+
frame_exist_flag = True
49+
else:
50+
frame_dict[slot_num - index - 1] = copy.deepcopy(black_image)
51+
52+
display_num_list = [1, 2, 4, 4, 6, 6, 9, 9, 9]
53+
for index in range(display_num_list[slot_num - 1]):
54+
if frame_dict.get(index, None) is None:
55+
frame_dict[index] = copy.deepcopy(black_image)
56+
57+
if not frame_exist_flag:
58+
frame_dict = None
59+
60+
return frame_dict
61+
62+
63+
class Node(DpgNodeABC):
64+
_ver = '0.0.1'
65+
66+
node_label = 'Image Alpha Blend'
67+
node_tag = 'ImageAlphaBlend'
68+
_max_slot_number = 2
69+
_slot_id = {}
70+
_alpha_min = 0.0
71+
_alpha_max = 1.0
72+
_alpha_default = 1.0
73+
_beta_min = 0.0
74+
_beta_max = 1.0
75+
_beta_default = 0.3
76+
_gamma_min = 0
77+
_gamma_max = 255
78+
_gamma_default = 0
79+
80+
_opencv_setting_dict = None
81+
82+
def __init__(self):
83+
pass
84+
85+
def add_node(
86+
self,
87+
parent,
88+
node_id,
89+
pos=[0, 0],
90+
opencv_setting_dict=None,
91+
callback=None,
92+
):
93+
# タグ名
94+
tag_node_name = str(node_id) + ':' + self.node_tag
95+
tag_node_input01_name = tag_node_name + ':' + self.TYPE_IMAGE + ':Input01'
96+
tag_node_input01_value_name = tag_node_name + ':' + self.TYPE_IMAGE + ':Input01Value'
97+
tag_node_input02_name = tag_node_name + ':' + self.TYPE_IMAGE + ':Input02'
98+
tag_node_input02_value_name = tag_node_name + ':' + self.TYPE_IMAGE + ':Input02Value'
99+
tag_node_input03_name = tag_node_name + ':' + self.TYPE_FLOAT + ':Input03'
100+
tag_node_input03_value_name = tag_node_name + ':' + self.TYPE_FLOAT + ':Input03Value'
101+
tag_node_input04_name = tag_node_name + ':' + self.TYPE_FLOAT + ':Input04'
102+
tag_node_input04_value_name = tag_node_name + ':' + self.TYPE_FLOAT + ':Input04Value'
103+
tag_node_input05_name = tag_node_name + ':' + self.TYPE_INT + ':Input05'
104+
tag_node_input05_value_name = tag_node_name + ':' + self.TYPE_INT + ':Input05Value'
105+
tag_node_output01_name = tag_node_name + ':' + self.TYPE_IMAGE + ':Output01'
106+
tag_node_output01_value_name = tag_node_name + ':' + self.TYPE_IMAGE + ':Output01Value'
107+
tag_node_output02_name = tag_node_name + ':' + self.TYPE_TIME_MS + ':Output02'
108+
tag_node_output02_value_name = tag_node_name + ':' + self.TYPE_TIME_MS + ':Output02Value'
109+
110+
# OpenCV向け設定
111+
self._opencv_setting_dict = opencv_setting_dict
112+
small_window_w = self._opencv_setting_dict['process_width']
113+
small_window_h = self._opencv_setting_dict['process_height']
114+
use_pref_counter = self._opencv_setting_dict['use_pref_counter']
115+
116+
# 初期化用黒画像
117+
black_image = np.zeros((small_window_w, small_window_h, 3))
118+
black_texture = convert_cv_to_dpg(
119+
black_image,
120+
small_window_w,
121+
small_window_h,
122+
)
123+
124+
# テクスチャ登録
125+
with dpg.texture_registry(show=False):
126+
dpg.add_raw_texture(
127+
small_window_w,
128+
small_window_h,
129+
black_texture,
130+
tag=tag_node_output01_value_name,
131+
format=dpg.mvFormat_Float_rgb,
132+
)
133+
134+
# スロットナンバー保持用Dict
135+
if tag_node_name not in self._slot_id:
136+
self._slot_id[tag_node_name] = 1
137+
138+
# ノード
139+
with dpg.node(
140+
tag=tag_node_name,
141+
parent=parent,
142+
label=self.node_label,
143+
pos=pos,
144+
):
145+
# 入力端子
146+
with dpg.node_attribute(
147+
tag=tag_node_input01_name,
148+
attribute_type=dpg.mvNode_Attr_Input,
149+
):
150+
dpg.add_text(
151+
tag=tag_node_input01_value_name,
152+
default_value='Input BGR image',
153+
)
154+
# 入力端子
155+
with dpg.node_attribute(
156+
tag=tag_node_input02_name,
157+
attribute_type=dpg.mvNode_Attr_Input,
158+
):
159+
dpg.add_text(
160+
tag=tag_node_input02_value_name,
161+
default_value='Input BGR image',
162+
)
163+
# 画像
164+
with dpg.node_attribute(
165+
tag=tag_node_output01_name,
166+
attribute_type=dpg.mvNode_Attr_Output,
167+
):
168+
dpg.add_image(tag_node_output01_value_name)
169+
# ヒステリシス
170+
with dpg.node_attribute(
171+
tag=tag_node_input03_name,
172+
attribute_type=dpg.mvNode_Attr_Input,
173+
):
174+
dpg.add_slider_float(
175+
tag=tag_node_input03_value_name,
176+
label="alpha val",
177+
width=small_window_w - 80,
178+
default_value=self._alpha_default,
179+
min_value=self._alpha_min,
180+
max_value=self._alpha_max,
181+
callback=None,
182+
)
183+
with dpg.node_attribute(
184+
tag=tag_node_input04_name,
185+
attribute_type=dpg.mvNode_Attr_Input,
186+
):
187+
dpg.add_slider_float(
188+
tag=tag_node_input04_value_name,
189+
label="beta val",
190+
width=small_window_w - 80,
191+
default_value=self._beta_default,
192+
min_value=self._beta_min,
193+
max_value=self._beta_max,
194+
callback=None,
195+
)
196+
with dpg.node_attribute(
197+
tag=tag_node_input05_name,
198+
attribute_type=dpg.mvNode_Attr_Input,
199+
):
200+
dpg.add_slider_int(
201+
tag=tag_node_input05_value_name,
202+
label="gamma val",
203+
width=small_window_w - 80,
204+
default_value=self._gamma_default,
205+
min_value=self._gamma_min,
206+
max_value=self._gamma_max,
207+
callback=None,
208+
)
209+
# 処理時間
210+
if use_pref_counter:
211+
with dpg.node_attribute(
212+
tag=tag_node_output02_name,
213+
attribute_type=dpg.mvNode_Attr_Output,
214+
):
215+
dpg.add_text(
216+
tag=tag_node_output02_value_name,
217+
default_value='elapsed time(ms)',
218+
)
219+
220+
return tag_node_name
221+
222+
def update(
223+
self,
224+
node_id,
225+
connection_list,
226+
node_image_dict,
227+
node_result_dict,
228+
):
229+
tag_node_name = str(node_id) + ':' + self.node_tag
230+
input_value03_tag = tag_node_name + ':' + self.TYPE_FLOAT + ':Input03Value'
231+
input_value04_tag = tag_node_name + ':' + self.TYPE_FLOAT + ':Input04Value'
232+
input_value05_tag = tag_node_name + ':' + self.TYPE_INT + ':Input05Value'
233+
output_value01_tag = tag_node_name + ':' + self.TYPE_IMAGE + ':Output01Value'
234+
output_value02_tag = tag_node_name + ':' + self.TYPE_TIME_MS + ':Output02Value'
235+
236+
small_window_w = self._opencv_setting_dict['process_width']
237+
small_window_h = self._opencv_setting_dict['process_height']
238+
use_pref_counter = self._opencv_setting_dict['use_pref_counter']
239+
draw_info_on_result = self._opencv_setting_dict['draw_info_on_result']
240+
241+
# 接続情報確認
242+
frame = None
243+
frame1 = None
244+
frame2 = None
245+
node_name_dict = {}
246+
connection_info_src = ''
247+
connection_info_src_dict = {}
248+
for connection_info in connection_list:
249+
250+
# タグ名からスロットナンバー取得
251+
slot_number = re.sub(r'\D', '', connection_info[1].split(':')[-1])
252+
if slot_number == '':
253+
continue
254+
slot_number = int(slot_number) - 1
255+
connection_type = connection_info[0].split(':')[2]
256+
connection_tag = connection_info[1].split(':')[3]
257+
if connection_type == self.TYPE_FLOAT:
258+
# 接続タグ取得
259+
source_tag = connection_info[0] + 'Value'
260+
destination_tag = connection_info[1] + 'Value'
261+
# 値更新
262+
input_value = round(float(dpg_get_value(source_tag)),3)
263+
if connection_tag == 'Input03':
264+
input_value = max([self._alpha_min, input_value])
265+
input_value = min([self._alpha_max, input_value])
266+
if connection_tag == 'Input04':
267+
input_value = max([self._beta_min, input_value])
268+
input_value = min([self._beta_max, input_value])
269+
dpg_set_value(destination_tag, input_value)
270+
if connection_type == self.TYPE_INT:
271+
# 接続タグ取得
272+
source_tag = connection_info[0] + 'Value'
273+
destination_tag = connection_info[1] + 'Value'
274+
# 値更新
275+
input_value = int(dpg_get_value(source_tag))
276+
if connection_tag == 'Input05':
277+
input_value = max([self._gamma_min, input_value])
278+
input_value = min([self._gamma_max, input_value])
279+
dpg_set_value(destination_tag, input_value)
280+
if connection_type == self.TYPE_IMAGE:
281+
# 画像取得元のノード名(ID付き)を取得
282+
connection_info_src = connection_info[0]
283+
connection_info_src = connection_info_src.split(':')[:2]
284+
node_name = connection_info_src[1]
285+
connection_info_src = ':'.join(connection_info_src)
286+
node_name_dict[slot_number] = node_name
287+
connection_info_src_dict[slot_number] = connection_info_src
288+
289+
# 画像取得
290+
291+
if len(connection_info_src_dict) == 1:
292+
connected_first_slot_no = (next(iter(connection_info_src_dict)))
293+
frame1 = node_image_dict.get(connection_info_src_dict[connected_first_slot_no])
294+
frame = frame1
295+
if len(connection_info_src_dict) == 2:
296+
frame1 = node_image_dict.get(connection_info_src_dict[0])
297+
frame2 = node_image_dict.get(connection_info_src_dict[1])
298+
frame = frame1
299+
300+
# アルファブレンド
301+
alpha_val = float(dpg_get_value(input_value03_tag))
302+
beta_val = float(dpg_get_value(input_value04_tag))
303+
gamma_val = int(dpg_get_value(input_value05_tag))
304+
305+
# 計測開始
306+
if frame is not None and use_pref_counter:
307+
start_time = time.perf_counter()
308+
309+
if len(connection_info_src_dict) == 2:
310+
if frame1 is not None and frame2 is not None:
311+
frame = image_process(frame1, frame2, alpha_val, beta_val, gamma_val)
312+
313+
# 計測終了
314+
if frame is not None and use_pref_counter:
315+
elapsed_time = time.perf_counter() - start_time
316+
elapsed_time = int(elapsed_time * 1000)
317+
dpg_set_value(output_value02_tag,
318+
str(elapsed_time).zfill(4) + 'ms')
319+
320+
# 描画
321+
if frame is not None:
322+
texture = convert_cv_to_dpg(
323+
frame,
324+
small_window_w,
325+
small_window_h,
326+
)
327+
dpg_set_value(output_value01_tag, texture)
328+
329+
return frame, None
330+
331+
def close(self, node_id):
332+
pass
333+
334+
def get_setting_dict(self, node_id):
335+
tag_node_name = str(node_id) + ':' + self.node_tag
336+
input_value03_tag = tag_node_name + ':' + self.TYPE_INT + ':Input03Value'
337+
338+
kernel_size = dpg_get_value(input_value03_tag)
339+
340+
pos = dpg.get_item_pos(tag_node_name)
341+
342+
setting_dict = {}
343+
setting_dict['ver'] = self._ver
344+
setting_dict['pos'] = pos
345+
setting_dict[input_value03_tag] = kernel_size
346+
347+
return setting_dict
348+
349+
def set_setting_dict(self, node_id, setting_dict):
350+
tag_node_name = str(node_id) + ':' + self.node_tag
351+
input_value03_tag = tag_node_name + ':' + self.TYPE_INT + ':Input02Value'
352+
353+
kernel_size = int(setting_dict[input_value03_tag])
354+
355+
dpg_set_value(input_value03_tag, kernel_size)

node_editor/setting/setting.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
"video_writer_directory": "./_VideoWriter",
1616
"use_pref_counter": true,
1717
"draw_info_on_result":true,
18-
"use_gpu":true
18+
"use_gpu":true,
19+
"use_serial":false
1920
}

0 commit comments

Comments
 (0)