1 /*****************************************************************************
2 * This file is part of gfxprim library. *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
19 * Copyright (C) 2009-2012 Cyril Hrubis <metan@ucw.cz> *
21 *****************************************************************************/
25 #include "core/GP_Debug.h"
26 #include "core/GP_GetPutPixel.h"
28 #include "filters/GP_Linear.h"
29 #include "filters/GP_EdgeDetection.h"
32 * Apply prewitt operator.
34 static int prewitt(const gp_pixmap
*src
, gp_pixmap
*dx
, gp_pixmap
*dy
,
35 gp_progress_cb
*callback
)
37 float smooth_kern
[3] = {1, 1, 1,};
38 float grad_kern
[3] = {-1, 0, 1};
40 if (gp_filter_vhlinear_convolution_raw(src
, 0, 0, src
->w
, src
->h
,
43 grad_kern
, 3, 1, callback
))
46 if (gp_filter_vhlinear_convolution_raw(src
, 0, 0, src
->w
, src
->h
,
49 smooth_kern
, 3, 1, callback
))
56 * Apply sobel operator.
58 static int sobel(const gp_pixmap
*src
, gp_pixmap
*dx
, gp_pixmap
*dy
,
59 gp_progress_cb
*callback
)
67 gp_convolution_params dx_conv
= {
83 if (gp_filter_convolution_raw(&dx_conv
))
92 gp_convolution_params dy_conv
= {
105 .callback
= callback
,
108 if (gp_filter_convolution_raw(&dy_conv
))
114 static int edge_detect(const gp_pixmap
*src
,
115 gp_pixmap
**E
, gp_pixmap
**Phi
, int type
,
116 gp_progress_cb
*callback
)
119 GP_ASSERT(src
->pixel_type
== GP_PIXEL_RGB888
);
123 dx
= gp_pixmap_copy(src
, 0);
124 dy
= gp_pixmap_copy(src
, 0);
126 if (dx
== NULL
|| dy
== NULL
)
131 if (sobel(src
, dx
, dy
, callback
))
135 if (prewitt(src
, dx
, dy
, callback
))
144 for (i
= 0; i
< src
->w
; i
++) {
145 for (j
= 0; j
< src
->h
; j
++) {
146 gp_pixel pix_x
= gp_getpixel_raw_24BPP(dx
, i
, j
);
147 gp_pixel pix_y
= gp_getpixel_raw_24BPP(dy
, i
, j
);
151 int RPhi
, GPhi
, BPhi
;
153 Rx
= GP_PIXEL_GET_R_RGB888(pix_x
);
154 Gx
= GP_PIXEL_GET_G_RGB888(pix_x
);
155 Bx
= GP_PIXEL_GET_B_RGB888(pix_x
);
157 Ry
= GP_PIXEL_GET_R_RGB888(pix_y
);
158 Gy
= GP_PIXEL_GET_G_RGB888(pix_y
);
159 By
= GP_PIXEL_GET_B_RGB888(pix_y
);
161 RE
= sqrt(Rx
*Rx
+ Ry
*Ry
) + 0.5;
162 GE
= sqrt(Gx
*Gx
+ Gy
*Gy
) + 0.5;
163 BE
= sqrt(Bx
*Bx
+ By
*By
) + 0.5;
165 gp_putpixel_raw_24BPP(dx
, i
, j
,
166 GP_PIXEL_CREATE_RGB888(RE
, GE
, BE
));
168 if (Rx
!= 0 && Ry
!= 0)
169 RPhi
= ((atan2(Rx
, Ry
) + M_PI
) * 255)/(2*M_PI
);
173 if (Gx
!= 0 && Gy
!= 0)
174 GPhi
= ((atan2(Gx
, Gy
) + M_PI
) * 255)/(2*M_PI
);
178 if (Bx
!= 0 && By
!= 0)
179 BPhi
= ((atan2(Bx
, By
) + M_PI
) * 255)/(2*M_PI
);
183 gp_putpixel_raw_24BPP(dy
, i
, j
,
184 GP_PIXEL_CREATE_RGB888(RPhi
, GPhi
, BPhi
));
205 int gp_filter_edge_sobel(const gp_pixmap
*src
,
206 gp_pixmap
**E
, gp_pixmap
**Phi
,
207 gp_progress_cb
*callback
)
209 GP_DEBUG(1, "Sobel edge detection image %ux%u", src
->w
, src
->h
);
211 return edge_detect(src
, E
, Phi
, 0, callback
);
214 int gp_filter_edge_prewitt(const gp_pixmap
*src
,
215 gp_pixmap
**E
, gp_pixmap
**Phi
,
216 gp_progress_cb
*callback
)
218 GP_DEBUG(1, "Prewitt edge detection image %ux%u", src
->w
, src
->h
);
220 return edge_detect(src
, E
, Phi
, 1, callback
);