-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.rs
235 lines (206 loc) · 6.91 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
// canny-edge-detector sample from https://github.com/KhronosGroup/openvx-samples
mod names;
mod print_attributes;
use crate::names::set_node_name;
use crate::print_attributes::{print_graph_attributes, print_node_attributes};
use libopenvx_sys::*;
use opencv::core::CV_8U;
use opencv::{
core::Size,
highgui::{destroy_all_windows, imshow, wait_key},
imgcodecs::{imread, IMREAD_COLOR},
imgproc::{resize, INTER_LINEAR},
prelude::*,
};
use openvx::*;
type Result<T> = opencv::Result<T>;
unsafe fn run() -> Result<()> {
let width: vx_uint32 = 512;
let height: vx_uint32 = 512;
let mut context = VxContext::create();
context.check_status().expect("Context was invalid");
context.enable_logging().expect("Unable to enable logging");
context
.enable_performance_counters()
.expect("Unable to enable performance counters");
let mut graph = VxGraph::create(&context);
graph
.check_status()
.expect("Graph was invalid")
.set_name("CANNY_GRAPH");
let mut input_rgb_image =
vxCreateImage(context.as_raw(), width, height, ImageType::RGB.to_raw());
let mut output_filtered_image =
vxCreateImage(context.as_raw(), width, height, ImageType::U8.to_raw());
error_check_object(input_rgb_image as vx_reference);
error_check_object(output_filtered_image as vx_reference);
let mut yuv_image =
vxCreateVirtualImage(graph.as_raw(), width, height, ImageType::IYUV.to_raw());
let mut luma_image =
vxCreateVirtualImage(graph.as_raw(), width, height, ImageType::U8.to_raw());
error_check_object(yuv_image as vx_reference);
error_check_object(luma_image as vx_reference);
let hyst = vxCreateThreshold(
context.as_raw(),
vx_threshold_type_e_VX_THRESHOLD_TYPE_RANGE as vx_enum,
vx_type_e_VX_TYPE_UINT8 as vx_enum,
);
let lower: vx_int32 = 130;
let upper: vx_int32 = 150;
vxSetThresholdAttribute(
hyst,
constants::thresholds::VX_THRESHOLD_ATTRIBUTE_THRESHOLD_LOWER,
&lower as *const _ as *const std::ffi::c_void,
std::mem::size_of_val(&lower) as vx_size,
);
vxSetThresholdAttribute(
hyst,
constants::thresholds::VX_THRESHOLD_ATTRIBUTE_THRESHOLD_UPPER,
&upper as *const _ as *const std::ffi::c_void,
std::mem::size_of_val(&upper) as vx_size,
);
error_check_object(hyst as vx_reference);
let gradient_size: vx_int32 = 3;
let mut nodes = vec![
set_node_name(
vxColorConvertNode(graph.as_raw(), input_rgb_image, yuv_image),
"RGB_TO_YUV",
),
set_node_name(
vxChannelExtractNode(
graph.as_raw(),
yuv_image,
vx_channel_e_VX_CHANNEL_Y as vx_enum,
luma_image,
),
"EXTRACT_LUMA",
),
set_node_name(
vxCannyEdgeDetectorNode(
graph.as_raw(),
luma_image,
hyst,
gradient_size,
vx_norm_type_e_VX_NORM_L1 as vx_enum,
output_filtered_image,
),
"CANNY_EDGE",
),
];
for node in nodes.iter_mut() {
error_check_object(*node as vx_reference);
}
error_check_status(vxVerifyGraph(graph.as_raw()));
let image = imread(".images/selfie.jpg", IMREAD_COLOR)?;
let mut resized = Mat::default();
resize(
&image,
&mut resized,
Size {
width: width as i32,
height: height as i32,
},
0f64,
0f64,
INTER_LINEAR,
)?;
imshow("Input Image", &resized)?;
let cv_rgb_image_region = vx_rectangle_t {
start_x: 0 as vx_uint32,
start_y: 0 as vx_uint32,
end_x: width,
end_y: height,
};
let cv_rgb_image_layout = vx_imagepatch_addressing_t {
stride_x: 3 as vx_int32,
stride_y: resized.mat_step().get(0) as vx_int32,
// Default isn't implemented; not sure about these, but zeros seem to work.
dim_x: 0 as vx_uint32,
dim_y: 0 as vx_uint32,
scale_x: 0 as vx_uint32,
scale_y: 0 as vx_uint32,
step_x: 0 as vx_uint32,
step_y: 0 as vx_uint16,
stride_x_bits: 0 as vx_uint16,
};
let cv_rgb_image_buffer: *mut vx_uint8 = resized.data_mut();
error_check_status(vxCopyImagePatch(
input_rgb_image,
&cv_rgb_image_region,
0,
&cv_rgb_image_layout,
cv_rgb_image_buffer as *mut std::ffi::c_void,
vx_accessor_e_VX_WRITE_ONLY as vx_enum,
vx_memory_type_e_VX_MEMORY_TYPE_HOST as vx_enum,
));
error_check_status(vxProcessGraph(graph.as_raw()));
let rect = vx_rectangle_t {
start_x: 0 as vx_uint32,
start_y: 0 as vx_uint32,
end_x: width,
end_y: height,
};
let mut map_id: vx_map_id = 0usize;
let mut addr: vx_imagepatch_addressing_t = vx_imagepatch_addressing_t {
dim_x: 0 as vx_uint32,
dim_y: 0 as vx_uint32,
stride_x: 0 as vx_int32,
stride_y: 0 as vx_int32,
scale_x: 0 as vx_uint32,
scale_y: 0 as vx_uint32,
step_x: 0 as vx_uint32,
step_y: 0 as vx_uint16,
stride_x_bits: 0 as vx_uint16,
};
let mut ptr: *mut std::ffi::c_void = std::ptr::null_mut();
error_check_status(vxMapImagePatch(
output_filtered_image,
&rect,
0 as vx_uint32,
&mut map_id,
&mut addr,
&mut ptr,
vx_accessor_e_VX_READ_ONLY as vx_enum,
vx_memory_type_e_VX_MEMORY_TYPE_HOST as vx_enum,
vx_map_flag_e_VX_NOGAP_X as vx_uint32,
));
let mat = Mat::new_rows_cols_with_data_unsafe(
height as i32,
width as i32,
CV_8U,
ptr,
addr.stride_y as usize,
)?;
print_graph_attributes(&mut graph);
for node in nodes.iter_mut() {
print_node_attributes(*node);
error_check_status(vxReleaseNode(node));
}
imshow("Canny Edge Detection", &mat)?;
wait_key(0)?;
destroy_all_windows()?;
error_check_status(vxUnmapImagePatch(output_filtered_image, map_id));
graph.release().expect("Releasing graph failed");
error_check_status(vxReleaseImage(&mut yuv_image));
error_check_status(vxReleaseImage(&mut luma_image));
error_check_status(vxReleaseImage(&mut input_rgb_image));
error_check_status(vxReleaseImage(&mut output_filtered_image));
context.release().expect("Releasing context failed");
Ok(())
}
fn error_check_object(r#ref: vx_reference) {
let status = unsafe { vxGetStatus(r#ref) };
let status = VxStatus::from(status);
if status != VxStatus::Success {
panic!("ERROR: failed with status {}", status);
}
}
fn error_check_status(status: vx_status) {
let status = VxStatus::from(status);
if status != VxStatus::Success {
panic!("ERROR: failed with status {}", status);
}
}
fn main() {
unsafe { run().unwrap() };
}