4949
5050import Catalano .Imaging .Filters .*;
5151import Catalano .Imaging .FastBitmap ;
52+ import Catalano .Imaging .Tools .ImageUtils ;
53+ import Catalano .Imaging .Tools .Kernel ;
5254import Catalano .Math .Functions .Gaussian ;
5355import Catalano .Math .Matrix ;
5456
6264 */
6365public class DifferenceOfGaussian implements IPhotometricFilter {
6466
65- private double sigma1 = 1.4D , sigma2 = 1.4D ;
66- private boolean normalize = true ;
67+ private double sigma1 ;
68+ private double sigma2 ;
69+ private double [][] gv1 ;
70+ private double [][] gv2 ;
71+
72+ /**
73+ * Get sigma 1.
74+ * @return Sigma value.
75+ */
76+ public double getSigma1 () {
77+ return sigma1 ;
78+ }
79+
80+ /**
81+ * Set sigma 1.
82+ * @param sigma1 Sigma value.
83+ */
84+ public void setSigma1 (double sigma1 ) {
85+ this .sigma1 = sigma1 ;
86+ BuildKernels ();
87+ }
88+
89+ /**
90+ * Get sigma 2.
91+ * @return Sigma value.
92+ */
93+ public double getSigma2 () {
94+ return sigma2 ;
95+ }
96+
97+ /**
98+ * Set sigma 2.
99+ * @param sigma2 Sigma value.
100+ */
101+ public void setSigma2 (double sigma2 ) {
102+ this .sigma2 = sigma2 ;
103+ BuildKernels ();
104+ }
67105
68106 /**
69107 * Initialize a new instance of the DifferenceOfGaussian class.
108+ * <br>
109+ * <br> Default:
110+ * <br> Sigma 1: 1
111+ * <br> Sigma 2: 2
70112 */
71113 public DifferenceOfGaussian () {
72114 this (1 ,2 );
@@ -80,18 +122,12 @@ public DifferenceOfGaussian() {
80122 * @param sigma2 Second sigma value.
81123 */
82124 public DifferenceOfGaussian (double sigma1 , double sigma2 ) {
83- this (sigma1 ,sigma2 ,true );
84- }
85-
86- public DifferenceOfGaussian (double sigma1 , double sigma2 , boolean normalize ){
87125 this .sigma1 = sigma1 ;
88126 this .sigma2 = sigma2 ;
89- this . normalize = normalize ;
127+ BuildKernels () ;
90128 }
91-
92- @ Override
93- public void applyInPlace (FastBitmap fastBitmap ) {
94-
129+
130+ private void BuildKernels (){
95131 int size1 = 2 * (int )Math .ceil (3 *sigma1 ) + 1 ;
96132 Gaussian ga = new Gaussian (sigma1 );
97133 double [][] g1 = ga .Kernel2D (size1 );
@@ -100,9 +136,21 @@ public void applyInPlace(FastBitmap fastBitmap) {
100136 ga .setSigma (sigma2 );
101137 double [][] g2 = ga .Kernel2D (size2 );
102138
139+ //Decompose kernels
140+ gv1 = Kernel .Decompose (g1 );
141+ gv2 = Kernel .Decompose (g2 );
142+ }
143+
144+ @ Override
145+ public void applyInPlace (FastBitmap fastBitmap ) {
146+
103147 if (fastBitmap .isGrayscale ()){
104- double [][] im1 = operateGray (fastBitmap , g1 );
105- double [][] im2 = operateGray (fastBitmap , g2 );
148+
149+ double [][] image = fastBitmap .toMatrixGrayAsDouble ();
150+ ImageUtils .Normalize (image );
151+
152+ double [][] im1 = ImageUtils .Convolution (image , gv1 [0 ], gv1 [1 ], true );
153+ double [][] im2 = ImageUtils .Convolution (image , gv2 [0 ], gv2 [1 ], true );
106154
107155 im1 = Matrix .Subtract (im1 , im2 );
108156
@@ -121,15 +169,14 @@ public void applyInPlace(FastBitmap fastBitmap) {
121169 fastBitmap .setGray (i , j , (int )Catalano .Math .Tools .Scale (min , max , 0 , 255 , im1 [i ][j ]));
122170 }
123171 }
124-
125- if (normalize ){
126- HistogramAdjust ha = new HistogramAdjust ();
127- ha .applyInPlace (fastBitmap );
128- }
172+
129173 }
130174 else if (fastBitmap .isRGB ()){
131- double [][][] im1 = operateRGB (fastBitmap , g1 );
132- double [][][] im2 = operateRGB (fastBitmap , g2 );
175+
176+ double [][][] image = fastBitmap .toMatrixRGBAsDouble ();
177+
178+ double [][][] im1 = ImageUtils .Convolution (image , gv1 [0 ], gv1 [1 ], true );
179+ double [][][] im2 = ImageUtils .Convolution (image , gv2 [0 ], gv2 [1 ], true );
133180
134181 //Subtract operation
135182 for (int i = 0 ; i < im1 .length ; i ++) {
@@ -168,100 +215,33 @@ else if(fastBitmap.isRGB()){
168215 }
169216 }
170217
171- if (normalize ){
172- HistogramAdjust ha = new HistogramAdjust ();
173- ha .applyInPlace (fastBitmap );
174- }
175- }
176- }
177-
178- private double [][] operateGray (FastBitmap fastBitmap , double [][] kernel ){
179- //Perform the convolution
180- int width = fastBitmap .getWidth ();
181- int height = fastBitmap .getHeight ();
182- double [][] response = new double [height ][width ];
183-
184- int Xline ,Yline ;
185- int lines = (kernel .length - 1 )/2 ;
186- double gray ;
187-
188- for (int x = 0 ; x < height ; x ++) {
189- for (int y = 0 ; y < width ; y ++) {
190- gray = 0 ;
191- for (int i = 0 ; i < kernel .length ; i ++) {
192- Xline = x + (i -lines );
193- for (int j = 0 ; j < kernel [0 ].length ; j ++) {
194- Yline = y + (j -lines );
195- if ((Xline >= 0 ) && (Xline < height ) && (Yline >=0 ) && (Yline < width )) {
196- gray += kernel [i ][j ] * fastBitmap .getGray (Xline , Yline );
197- }
198- else {
199-
200- int r = x + i - lines ;
201- int c = y + j - lines ;
218+ HistogramAdjust ha = new HistogramAdjust ();
219+ ha .applyInPlace (fastBitmap );
202220
203- if (r < 0 ) r = 0 ;
204- if (r >= height ) r = height - 1 ;
205-
206- if (c < 0 ) c = 0 ;
207- if (c >= width ) c = width - 1 ;
208-
209- gray += kernel [i ][j ] * fastBitmap .getGray (r , c );
210- }
211- }
212- }
213- response [x ][y ] = gray ;
214- }
215221 }
216-
217- return response ;
218222 }
219223
220- private double [][][] operateRGB (FastBitmap fastBitmap , double [][] kernel ){
221- //Perform the convolution
222- int width = fastBitmap .getWidth ();
223- int height = fastBitmap .getHeight ();
224- double [][][] response = new double [height ][width ][3 ];
224+ /**
225+ * Process the image as matrix.
226+ * @param image Image.
227+ * @param normalize True if the image needs to be normalized.
228+ * @return DoG of the image.
229+ */
230+ public double [][] Process (double [][] image , boolean normalize ){
225231
226- int Xline ,Yline ;
227- int lines = (kernel .length - 1 )/2 ;
228- double red ,green ,blue ;
232+ double [][] copy = Matrix .Copy (image );
229233
230- for (int x = 0 ; x < height ; x ++) {
231- for (int y = 0 ; y < width ; y ++) {
232- red = green = blue = 0 ;
233- for (int i = 0 ; i < kernel .length ; i ++) {
234- Xline = x + (i -lines );
235- for (int j = 0 ; j < kernel [0 ].length ; j ++) {
236- Yline = y + (j -lines );
237- if ((Xline >= 0 ) && (Xline < height ) && (Yline >=0 ) && (Yline < width )) {
238- red += kernel [i ][j ] * fastBitmap .getRed (Xline , Yline );
239- green += kernel [i ][j ] * fastBitmap .getGreen (Xline , Yline );
240- blue += kernel [i ][j ] * fastBitmap .getBlue (Xline , Yline );
241- }
242- else {
243-
244- int r = x + i - lines ;
245- int c = y + j - lines ;
246-
247- if (r < 0 ) r = 0 ;
248- if (r >= height ) r = height - 1 ;
249-
250- if (c < 0 ) c = 0 ;
251- if (c >= width ) c = width - 1 ;
234+ ImageUtils .Normalize (copy );
235+
236+ double [][] im1 = ImageUtils .Convolution (copy , gv1 [0 ], gv1 [1 ]);
237+ double [][] im2 = ImageUtils .Convolution (copy , gv2 [0 ], gv2 [1 ]);
252238
253- red += kernel [i ][j ] * fastBitmap .getRed (r , c );
254- green += kernel [i ][j ] * fastBitmap .getGreen (r , c );
255- blue += kernel [i ][j ] * fastBitmap .getBlue (r , c );
256- }
257- }
258- }
259- response [x ][y ][0 ] = red ;
260- response [x ][y ][1 ] = green ;
261- response [x ][y ][2 ] = blue ;
262- }
239+ im1 = Matrix .Subtract (im1 , im2 );
240+
241+ if (normalize ){
242+ ImageUtils .Normalize (im1 );
263243 }
264244
265- return response ;
245+ return im1 ;
266246 }
267- }
247+ }
0 commit comments