This repository has been archived by the owner on Jan 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
contour.c
128 lines (103 loc) · 3.63 KB
/
contour.c
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
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include "contour.h"
#include "types_macros.h"
bool contour_trouver_pixel_noir(Image I, Point* mut_return) {
FOR_EACH_PIXEL(I, x, y) {
if (get_pixel_image(I, x, y) == NOIR && get_pixel_image(I, x, y - 1) == BLANC) {
*mut_return = set_point(x, y);
return true;
}
}
return false;
}
void contour_avancer(Point* current_position, Orientation direction) {
switch (direction) {
case Nord:
current_position->y--;
break;
case Est:
current_position->x++;
break;
case Sud:
current_position->y++;
break;
case Ouest:
current_position->x--;
break;
}
}
Orientation contour_gauche(Orientation o) {
// Les orientations sont en réalité des entiers dans [0; 4[
return (o + 3) % 4;
}
Orientation contour_droit(Orientation o) {
// Les orientations sont en réalité des entiers dans [0; 4[
return (o + 1) % 4;
}
Orientation contour_nouvelle_orientation(Image I, Point current_position, Orientation current_orientation) {
Pixel g;
Pixel d;
switch (current_orientation) {
case Nord:
g = get_pixel_image(I, current_position.x, current_position.y);
d = get_pixel_image(I, current_position.x + 1, current_position.y);
break;
case Est:
g = get_pixel_image(I, current_position.x + 1, current_position.y);
d = get_pixel_image(I, current_position.x + 1, current_position.y + 1);
break;
case Sud:
g = get_pixel_image(I, current_position.x + 1, current_position.y + 1);
d = get_pixel_image(I, current_position.x, current_position.y + 1);
break;
case Ouest:
g = get_pixel_image(I, current_position.x, current_position.y + 1);
d = get_pixel_image(I, current_position.x, current_position.y);
break;
}
if (g == NOIR) return contour_gauche(current_orientation);
if (d == BLANC) return contour_droit(current_orientation);
return current_orientation;
}
Mask contour_init_mask(Image I) {
Image mask = creer_image(I.L, I.H);
FOR_EACH_PIXEL(mask, x, y) {
Pixel p;
if ((get_pixel_image(I, x, y) == NOIR) && (get_pixel_image(I, x, y - 1) == BLANC)) {
p = NOIR;
} else {
p = BLANC;
}
set_pixel_image(mask, x, y, p);
}
return mask;
}
Contour contour(Image I, Mask mask) {
assert(I.L == mask.L && I.H == mask.H);
Point start;
if (contour_trouver_pixel_noir(mask, &start)) {
// Coin haut-gauche du pixel
start = add_point(start, set_point(-1, -1));
// Accumulateur pour le contour
ListePoint acc = liste_point_new();
Point current_position = start;
Orientation current_orientation = Est;
while (true) {
liste_point_push(&acc, current_position);
if (current_orientation == Est) {
set_pixel_image(mask, current_position.x + 1, current_position.y + 1, BLANC);
}
contour_avancer(¤t_position, current_orientation);
current_orientation = contour_nouvelle_orientation(I, current_position, current_orientation);
if ((current_position.x == start.x) && (current_position.y == start.y) && (current_orientation == Est)) {
liste_point_push(&acc, current_position);
return acc;
}
}
} else {
// Contour vide = "pas de contour trouvé"
return liste_point_new();
}
}