1 /** 2 Module containts optical flow plotting functions. 3 4 Copyright: Copyright Relja Ljubobratovic 2016. 5 6 Authors: Relja Ljubobratovic 7 8 License: $(LINK3 http://www.boost.org/LICENSE_1_0.txt, Boost Software License - Version 1.0). 9 */ 10 11 module dcv.plot.opticalflow; 12 13 import mir.ndslice.slice : Slice, sliced, SliceKind; 14 import mir.ndslice.algorithm; 15 16 /** 17 * Draw color-coded optical flow. 18 * 19 * params: 20 * flow = Optical flow displacement vectors. 21 * maxSize = Value which is considered to be the maximal 22 * displacement value for color saturation. Default is 23 * 0, which gets reset in the algorithm to 10% of image 24 * diagonal length. 25 * 26 * returns: 27 * RGB image of color-coded optical flow. 28 */ 29 Slice!(SliceKind.contiguous, [3], ubyte*) colorCode(Slice!(SliceKind.contiguous, [3], float*) flow, float maxSize = 0) 30 { 31 import std.math : sqrt; 32 import std.array : array; 33 34 import dcv.core.algorithm : ranged; 35 import dcv.imgproc.color : hsv2rgb; 36 37 if (maxSize == 0) 38 { 39 maxSize = (cast(float)(flow.length!0) ^^ 2 + cast(float)(flow.length!1) ^^ 2).sqrt; 40 maxSize *= 0.1; // expect max flow displacement to be 10% of the diagonal 41 } 42 43 auto hsv = new float[flow.length!0 * flow.length!1 * 3].sliced(flow.length!0, flow.length!1, 3); 44 45 foreach (r; 0 .. flow.length!0) 46 { 47 foreach (c; 0 .. flow.length!1) 48 { 49 import std.math : sqrt, atan2, PI; 50 51 float fx = flow[r, c, 0]; 52 float fy = flow[r, c, 1]; 53 54 float rad = sqrt(fx * fx + fy * fy); 55 float a = atan2(fy, fx) / PI; 56 57 auto pix = hsv[r, c]; 58 pix[0] = a * 180.0f + 180.0f; 59 pix[1] = rad; 60 pix[2] = 1.0f; 61 } 62 } 63 64 hsv[0 .. $, 0 .. $, 1].ranged(0.0f, maxSize)[] /= maxSize; 65 66 return hsv.hsv2rgb!ubyte; // Convert to RGB, and return... 67 }