1 /*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 - This software is distributed in the hope that it will be
4 - useful, but with NO WARRANTY OF ANY KIND.
5 - No author or distributor accepts responsibility to anyone for the
6 - consequences of using this software, or for whether it serves any
7 - particular purpose or works at all, unless he or she says so in
8 - writing. Everyone is granted permission to copy, modify and
9 - redistribute this source code, for commercial or non-commercial
10 - purposes, with the following restrictions: (1) the origin of this
11 - source code must not be misrepresented; (2) modified versions must
12 - be plainly marked as such; and (3) this notice may not be removed
13 - or altered from any source or modified source distribution.
14 *====================================================================*/
15
16 /*
17 * colormorph.c
18 *
19 * Top-level color morphological operations
20 *
21 * PIX *pixColorMorph()
22 *
23 * Method: Algorithm by van Herk and Gil and Werman, 1992
24 * Apply grayscale morphological operations separately
25 * to each component.
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include "allheaders.h"
31
32
33 /*-----------------------------------------------------------------*
34 * Top-level color morphological operations *
35 *-----------------------------------------------------------------*/
36 /*!
37 * pixColorMorph()
38 *
39 * Input: pixs
40 * type (L_MORPH_DILATE, L_MORPH_ERODE, L_MORPH_OPEN,
41 * or L_MORPH_CLOSE)
42 * hsize (of Sel; must be odd; origin implicitly in center)
43 * vsize (ditto)
44 * Return: pixd
45 *
46 * Notes:
47 * (1) This does the morph operation on each component separately,
48 * and recombines the result.
49 * (2) Sel is a brick with all elements being hits.
50 * (3) If hsize = vsize = 1, just returns a copy.
51 */
52 PIX *
pixColorMorph(PIX * pixs,l_int32 type,l_int32 hsize,l_int32 vsize)53 pixColorMorph(PIX *pixs,
54 l_int32 type,
55 l_int32 hsize,
56 l_int32 vsize)
57 {
58 PIX *pixr, *pixg, *pixb, *pixrm, *pixgm, *pixbm, *pixd;
59
60 PROCNAME("pixColorMorph");
61
62 if (!pixs)
63 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
64 if (pixGetDepth(pixs) != 32)
65 return (PIX *)ERROR_PTR("pixs not 32 bpp", procName, NULL);
66 if (type != L_MORPH_DILATE && type != L_MORPH_ERODE &&
67 type != L_MORPH_OPEN && type != L_MORPH_CLOSE)
68 return (PIX *)ERROR_PTR("invalid morph type", procName, NULL);
69 if (hsize < 1 || vsize < 1)
70 return (PIX *)ERROR_PTR("hsize or vsize < 1", procName, NULL);
71 if ((hsize & 1) == 0 ) {
72 L_WARNING("horiz sel size must be odd; increasing by 1", procName);
73 hsize++;
74 }
75 if ((vsize & 1) == 0 ) {
76 L_WARNING("vert sel size must be odd; increasing by 1", procName);
77 vsize++;
78 }
79
80 if (hsize == 1 && vsize == 1)
81 return pixCopy(NULL, pixs);
82
83 pixr = pixGetRGBComponent(pixs, COLOR_RED);
84 pixg = pixGetRGBComponent(pixs, COLOR_GREEN);
85 pixb = pixGetRGBComponent(pixs, COLOR_BLUE);
86 if (type == L_MORPH_DILATE) {
87 pixrm = pixDilateGray(pixr, hsize, vsize);
88 pixgm = pixDilateGray(pixg, hsize, vsize);
89 pixbm = pixDilateGray(pixb, hsize, vsize);
90 }
91 else if (type == L_MORPH_ERODE) {
92 pixrm = pixErodeGray(pixr, hsize, vsize);
93 pixgm = pixErodeGray(pixg, hsize, vsize);
94 pixbm = pixErodeGray(pixb, hsize, vsize);
95 }
96 else if (type == L_MORPH_OPEN) {
97 pixrm = pixOpenGray(pixr, hsize, vsize);
98 pixgm = pixOpenGray(pixg, hsize, vsize);
99 pixbm = pixOpenGray(pixb, hsize, vsize);
100 }
101 else { /* type == L_MORPH_CLOSE */
102 pixrm = pixCloseGray(pixr, hsize, vsize);
103 pixgm = pixCloseGray(pixg, hsize, vsize);
104 pixbm = pixCloseGray(pixb, hsize, vsize);
105 }
106 pixd = pixCreateRGBImage(pixrm, pixgm, pixbm);
107 pixDestroy(&pixr);
108 pixDestroy(&pixrm);
109 pixDestroy(&pixg);
110 pixDestroy(&pixgm);
111 pixDestroy(&pixb);
112 pixDestroy(&pixbm);
113
114 return pixd;
115 }
116
117
118
119