1 module dcv.example.imgmanip;
2 
3 /**
4  * Corner extraction example, by using Harris and Shi-Tomasi algorithms.
5  */
6 
7 import mir.ndslice;
8 
9 import dcv.core;
10 import dcv.features;
11 import dcv.imgproc.color;
12 import dcv.imgproc.filter;
13 import dcv.io;
14 import dcv.plot;
15 
16 import ggplotd.ggplotd;
17 import ggplotd.geom;
18 import ggplotd.aes;
19 
20 
21 void main()
22 {
23     // read source image
24     auto image = imread("../data/building.png");
25 
26     // prepare working sliced
27     auto imslice = image.sliced!ubyte;
28     auto imfslice = imslice.as!float.slice;
29     auto gray = imfslice.rgb2gray;
30 
31     // make copies to draw corners 
32     auto pixelSize = imslice.elementsCount;
33     auto shiTomasiDraw = imslice.slice;
34     auto harrisDraw = imslice.slice;
35 
36     // estimate corner response for each of corner algorithms by using 5x5 window.
37     auto shiTomasiResponse = shiTomasiCorners(gray, 5).filterNonMaximum;
38     auto harrisResponse = harrisCorners(gray, 5).filterNonMaximum;
39 
40     // extract corners from the response matrix ( extract 100 corners, where each response is larger than 0.)
41     auto shiTomasiCorners = extractCorners(shiTomasiResponse, 100, 0.0f).slice.field;
42     auto harrisCorners = extractCorners(harrisResponse, 100, 0.0f).slice.field;
43 
44     // visualize corner response, and write it to disk.
45     visualizeCornerResponse(harrisResponse, "harrisResponse");
46     visualizeCornerResponse(shiTomasiResponse, "shiTomasiResponse");
47 
48     // plot corner points on image.
49     cornerPlot(harrisDraw, harrisCorners, "harrisCorners");
50     cornerPlot(shiTomasiDraw, shiTomasiCorners, "shiTomasiCorners");
51 
52     waitKey();
53 }
54 
55 void visualizeCornerResponse(SliceKind kind)(Slice!(kind, [2], float*) response, string windowName)
56 {
57     response
58         // scale values in the response matrix for easier visualization.
59         .ranged(0f, 255f)
60         .as!ubyte
61         .slice
62         // Show the window
63         .imshow(windowName) 
64         .image
65         // ... but also write it to disk.
66         .imwrite("result/" ~ windowName ~ ".png");
67 }
68 
69 void cornerPlot(SliceKind kind)(Slice!(kind, [3], ubyte*) slice, size_t[2][] corners, string windowName)
70 {
71     import std.array : array;
72     import std.algorithm.iteration : map;
73 
74     // separate coordinate values
75     auto xs = corners.map!(e => e[1]);
76     auto ys = corners.map!(e => e[0]);
77 
78     auto aes = Aes!(typeof(xs), "x", typeof(ys), "y", bool[], "fill", string[], "colour")
79                    (xs, ys, false.repeat(xs.length).array, "red".repeat(xs.length).array);
80 
81     auto gg = GGPlotD().put(geomPoint(aes));
82 
83     // plot corners on the same figure, and save it's image to disk.
84     slice.plot(gg, windowName).image().imwrite("result/" ~ windowName ~ ".png");
85 }