The open source OpenXR runtime
at main 195 lines 4.0 kB view raw
1// Copyright 2019, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief HSV debug viewer code. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @ingroup aux_tracking 8 */ 9 10#include "util/u_misc.h" 11#include "util/u_debug.h" 12#include "util/u_format.h" 13#include "tracking/t_tracking.h" 14 15#include <opencv2/opencv.hpp> 16 17 18/* 19 * 20 * Defines and structs 21 * 22 */ 23 24#define HSV_WIN "HSV Filter Tester" 25 26/*! 27 * An @ref xrt_frame_sink related to debug viewing of HSV. 28 * @implements xrt_frame_sink 29 * @implements xrt_frame_node 30 */ 31class DebugHSVViewer 32{ 33public: 34 struct xrt_frame_sink base = {}; 35 struct xrt_frame_node node = {}; 36 37 struct xrt_frame_sink *passthrough; 38 39 cv::Mat bgr; 40 41 int lum_value = 0; 42 43 // No need to initialize these 44 struct t_convert_table yuv_to_rgb_table; 45 struct t_hsv_filter_large_table hsv_large; 46 struct t_hsv_filter_optimized_table hsv_opt; 47}; 48 49 50/* 51 * 52 * Debug functions. 53 * 54 */ 55 56static void 57process_pixel(bool f1, bool f1_diff, uint8_t *hsv_cap, uint8_t *hsv_opt, uint8_t *hsv_diff, const uint8_t *rgb) 58{ 59 if (f1) { 60 hsv_cap[0] = rgb[2]; 61 hsv_cap[1] = rgb[1]; 62 hsv_cap[2] = rgb[0]; 63 } else { 64 hsv_cap[0] = 0; 65 hsv_cap[1] = 0; 66 hsv_cap[2] = 0; 67 } 68 69 if (f1_diff) { 70 hsv_opt[0] = rgb[2]; 71 hsv_opt[1] = rgb[1]; 72 hsv_opt[2] = rgb[0]; 73 } else { 74 hsv_opt[0] = 0; 75 hsv_opt[1] = 0; 76 hsv_opt[2] = 0; 77 } 78 79 if (f1 > f1_diff) { 80 hsv_diff[0] = 0xff; 81 hsv_diff[1] = 0; 82 hsv_diff[2] = 0; 83 } else if (f1 < f1_diff) { 84 hsv_diff[0] = 0; 85 hsv_diff[1] = 0; 86 hsv_diff[2] = 0xff; 87 } else { 88 hsv_diff[0] = 0; 89 hsv_diff[1] = 0; 90 hsv_diff[2] = 0; 91 } 92} 93 94#define SIZE 256 95#define NUM_CHAN 4 96 97static void 98process_frame(DebugHSVViewer &d, struct xrt_frame *xf) 99{ 100 uint32_t width = SIZE * 3; 101 uint32_t height = SIZE * NUM_CHAN; 102 103 auto &bgr = d.bgr; 104 if (bgr.rows != (int)height || bgr.cols != (int)width) { 105 bgr = cv::Mat(height, width, CV_8UC3); 106 } 107 108 for (uint32_t yp = 0; yp < SIZE; yp++) { 109 for (int chan = 0; chan < NUM_CHAN; chan++) { 110 auto *hsv_cap = bgr.ptr<uint8_t>(yp + SIZE * chan); 111 auto *hsv_opt = bgr.ptr<uint8_t>(yp + SIZE * chan) + 256 * 3; 112 auto *hsv_diff = bgr.ptr<uint8_t>(yp + SIZE * chan) + 512 * 3; 113 int mask = 1 << chan; 114 115 for (uint32_t xp = 0; xp < SIZE; xp++) { 116 int y = d.lum_value; 117 int u = yp; 118 int v = xp; 119 120 uint8_t *rgb = d.yuv_to_rgb_table.v[y][u][v]; 121 uint8_t large = d.hsv_large.v[y][u][v]; 122 uint8_t opt = t_hsv_filter_sample(&d.hsv_opt, y, u, v); 123 124 large = (large & mask) != 0; 125 opt = (opt & mask) != 0; 126 127 process_pixel(large, opt, hsv_cap, hsv_opt, hsv_diff, rgb); 128 129 hsv_cap += 3; 130 hsv_opt += 3; 131 hsv_diff += 3; 132 } 133 } 134 } 135 136 cv::imshow(HSV_WIN, bgr); 137} 138 139 140/* 141 * 142 * Exported functions. 143 * 144 */ 145 146extern "C" void 147t_debug_hsv_viewer_frame(struct xrt_frame_sink *xsink, struct xrt_frame *xf) 148{ 149 auto &d = *(class DebugHSVViewer *)xsink; 150 151 process_frame(d, xf); 152 153 d.passthrough->push_frame(d.passthrough, xf); 154} 155 156extern "C" void 157t_debug_hsv_viewer_break_apart(struct xrt_frame_node *node) 158{} 159 160extern "C" void 161t_debug_hsv_viewer_destroy(struct xrt_frame_node *node) 162{ 163 auto *d = container_of(node, DebugHSVViewer, node); 164 delete d; 165} 166 167extern "C" int 168t_debug_hsv_viewer_create(struct xrt_frame_context *xfctx, 169 struct xrt_frame_sink *passthrough, 170 struct xrt_frame_sink **out_sink) 171{ 172 auto &d = *(new DebugHSVViewer()); 173 174 cv::namedWindow(HSV_WIN); 175 176 cv::createTrackbar("Luma", HSV_WIN, &d.lum_value, 255, NULL); 177 178 cv::startWindowThread(); 179 180 d.base.push_frame = t_debug_hsv_viewer_frame; 181 d.node.break_apart = t_debug_hsv_viewer_break_apart; 182 d.node.destroy = t_debug_hsv_viewer_destroy; 183 d.passthrough = passthrough; 184 185 t_convert_make_y8u8v8_to_r8g8b8(&d.yuv_to_rgb_table); 186 struct t_hsv_filter_params params = T_HSV_DEFAULT_PARAMS(); 187 t_hsv_build_large_table(&params, &d.hsv_large); 188 t_hsv_build_optimized_table(&params, &d.hsv_opt); 189 190 xrt_frame_context_add(xfctx, &d.node); 191 192 *out_sink = &d.base; 193 194 return 0; 195}