JWS C Library
C language utility library
|
00001 /* 00002 * This work is licensed under a Creative Commons 00003 * Attribution-Noncommercial-Share Alike 3.0 United States License. 00004 * 00005 * http://creativecommons.org/licenses/by-nc-sa/3.0/us/ 00006 * 00007 * You are free: 00008 * 00009 * to Share - to copy, distribute, display, and perform the work 00010 * to Remix - to make derivative works 00011 * 00012 * Under the following conditions: 00013 * 00014 * Attribution. You must attribute the work in the manner specified by the 00015 * author or licensor (but not in any way that suggests that they endorse you 00016 * or your use of the work). 00017 * 00018 * Noncommercial. You may not use this work for commercial purposes. 00019 * 00020 * Share Alike. If you alter, transform, or build upon this work, you may 00021 * distribute the resulting work only under the same or similar license to 00022 * this one. 00023 * 00024 * For any reuse or distribution, you must make clear to others the license 00025 * terms of this work. The best way to do this is by including this header. 00026 * 00027 * Any of the above conditions can be waived if you get permission from the 00028 * copyright holder. 00029 * 00030 * Apart from the remix rights granted under this license, nothing in this 00031 * license impairs or restricts the author's moral rights. 00032 */ 00033 00034 00046 #include <jwsc/config.h> 00047 00048 #include <stdlib.h> 00049 #include <inttypes.h> 00050 #include <math.h> 00051 #include <assert.h> 00052 00053 #include "jwsc/base/error.h" 00054 #include "jwsc/prob/pdf.h" 00055 #include "jwsc/matblock/matblock.h" 00056 #include "jwsc/matblock/matblock_math.h" 00057 #include "jwsc/filter/3d.h" 00058 00059 00061 #define PI 3.14159265358979323846 00062 00063 00088 Error* create_auto_3d_gaussian_filter_f 00089 ( 00090 Matblock_f** h_out, 00091 float mat_sigma, 00092 float row_sigma, 00093 float col_sigma 00094 ) 00095 { 00096 uint32_t num_mats, num_rows, num_cols; 00097 00098 if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++; 00099 if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++; 00100 if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++; 00101 00102 return create_3d_gaussian_filter_f(h_out, mat_sigma, row_sigma, col_sigma, 00103 num_mats, num_rows, num_cols); 00104 } 00105 00123 Error* create_auto_3d_gaussian_filter_d 00124 ( 00125 Matblock_d** h_out, 00126 double mat_sigma, 00127 double row_sigma, 00128 double col_sigma 00129 ) 00130 { 00131 uint32_t num_mats, num_rows, num_cols; 00132 00133 if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++; 00134 if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++; 00135 if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++; 00136 00137 return create_3d_gaussian_filter_d(h_out, mat_sigma, row_sigma, col_sigma, 00138 num_mats, num_rows, num_cols); 00139 } 00140 00175 Error* create_3d_gaussian_filter_f 00176 ( 00177 Matblock_f** h_out, 00178 float mat_sigma, 00179 float row_sigma, 00180 float col_sigma, 00181 uint32_t num_mats, 00182 uint32_t num_rows, 00183 uint32_t num_cols 00184 ) 00185 { 00186 uint32_t mat, row, col; 00187 uint32_t m, r, c; 00188 float x, y, z; 00189 float x_gauss, y_gauss, z_gauss; 00190 float gauss; 00191 Matblock_f* h; 00192 00193 if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01) 00194 { 00195 return JWSC_EARG("Sigma for Gaussian is too small"); 00196 } 00197 00198 create_matblock_f(h_out, num_mats, num_rows, num_cols); 00199 h = *h_out; 00200 00201 #if defined JWSC_HAVE_SLATEC || defined JWSC_HAVE_ERF 00202 for (mat = 0; mat < ceil(0.5*num_mats); mat++) 00203 { 00204 z = (ceil(0.5*num_mats) - mat - 1); 00205 z_gauss = integrate_gaussian_pdf_d(0, mat_sigma, z, z+1); 00206 for (row = 0; row < ceil(0.5*num_rows); row++) 00207 { 00208 y = (ceil(0.5*num_rows) - row - 1); 00209 y_gauss = integrate_gaussian_pdf_d(0, row_sigma, y, y+1); 00210 for (col = 0; col < ceil(0.5*num_cols); col++) 00211 { 00212 x = (ceil(0.5*num_cols) - col - 1); 00213 x_gauss = integrate_gaussian_pdf_d(0, col_sigma, x, x+1); 00214 gauss = x_gauss*y_gauss*z_gauss; 00215 00216 m = mat; r = row; c = col; 00217 h->elts[ m ][ r ][ c ] = gauss; 00218 00219 m = mat; r = row; c = num_cols-col-1; 00220 h->elts[ m ][ r ][ c ] = gauss; 00221 00222 m = mat; r = num_rows-row-1; c = col; 00223 h->elts[ m ][ r ][ c ] = gauss; 00224 00225 m = mat; r = num_rows-row-1; c = num_cols-col-1; 00226 h->elts[ m ][ r ][ c ] = gauss; 00227 00228 m = num_mats-mat-1; r = row; c = col; 00229 h->elts[ m ][ r ][ c ] = gauss; 00230 00231 m = num_mats-mat-1; r = row; c = num_cols-col-1; 00232 h->elts[ m ][ r ][ c ] = gauss; 00233 00234 m = num_mats-mat-1; r = num_rows-row-1; c = col; 00235 h->elts[ m ][ r ][ c ] = gauss; 00236 00237 m = num_mats-mat-1; r = num_rows-row-1; c = num_cols-col-1; 00238 h->elts[ m ][ r ][ c ] = gauss; 00239 } 00240 } 00241 } 00242 #else 00243 for (mat = 0; mat < ceil(0.5*num_mats); mat++) 00244 { 00245 z = (ceil(0.5*num_mats) - mat - 1); 00246 z_gauss = gaussian_pdf_d(0, row_sigma, z+0.5); 00247 for (row = 0; row < ceil(0.5*num_rows); row++) 00248 { 00249 y = (ceil(0.5*num_rows) - row - 1); 00250 y_gauss = gaussian_pdf_d(0, row_sigma, y+0.5); 00251 for (col = 0; col < ceil(0.5*num_cols); col++) 00252 { 00253 x = (ceil(0.5*num_cols) - col - 1); 00254 x_gauss = gaussian_pdf_d(0, col_sigma, x+0.5); 00255 gauss = x_gauss*y_gauss*z_gauss; 00256 00257 m = mat; r = row; c = col; 00258 h->elts[ m ][ r ][ c ] = gauss; 00259 00260 m = mat; r = row; c = num_cols-col-1; 00261 h->elts[ m ][ r ][ c ] = gauss; 00262 00263 m = mat; r = num_rows-row-1; c = col; 00264 h->elts[ m ][ r ][ c ] = gauss; 00265 00266 m = mat; r = num_rows-row-1; c = num_cols-col-1; 00267 h->elts[ m ][ r ][ c ] = gauss; 00268 00269 m = num_mats-mat-1; r = row; c = col; 00270 h->elts[ m ][ r ][ c ] = gauss; 00271 00272 m = num_mats-mat-1; r = row; c = num_cols-col-1; 00273 h->elts[ m ][ r ][ c ] = gauss; 00274 00275 m = num_mats-mat-1; r = num_rows-row-1; c = col; 00276 h->elts[ m ][ r ][ c ] = gauss; 00277 00278 m = num_mats-mat-1; r = num_rows-row-1; c = num_cols-col-1; 00279 h->elts[ m ][ r ][ c ] = gauss; 00280 } 00281 } 00282 } 00283 #endif 00284 00285 return NULL; 00286 } 00287 00310 Error* create_3d_gaussian_filter_d 00311 ( 00312 Matblock_d** h_out, 00313 double mat_sigma, 00314 double row_sigma, 00315 double col_sigma, 00316 uint32_t num_mats, 00317 uint32_t num_rows, 00318 uint32_t num_cols 00319 ) 00320 { 00321 uint32_t mat, row, col; 00322 uint32_t m, r, c; 00323 double x, y, z; 00324 double x_gauss, y_gauss, z_gauss; 00325 double gauss; 00326 Matblock_d* h; 00327 00328 if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01) 00329 { 00330 return JWSC_EARG("Sigma for Gaussian is too small"); 00331 } 00332 00333 create_matblock_d(h_out, num_mats, num_rows, num_cols); 00334 h = *h_out; 00335 00336 #if defined JWSC_HAVE_SLATEC || defined JWSC_HAVE_ERF 00337 for (mat = 0; mat < ceil(0.5*num_mats); mat++) 00338 { 00339 z = (ceil(0.5*num_mats) - mat - 1); 00340 z_gauss = integrate_gaussian_pdf_d(0, mat_sigma, z, z+1); 00341 for (row = 0; row < ceil(0.5*num_rows); row++) 00342 { 00343 y = (ceil(0.5*num_rows) - row - 1); 00344 y_gauss = integrate_gaussian_pdf_d(0, row_sigma, y, y+1); 00345 for (col = 0; col < ceil(0.5*num_cols); col++) 00346 { 00347 x = (ceil(0.5*num_cols) - col - 1); 00348 x_gauss = integrate_gaussian_pdf_d(0, col_sigma, x, x+1); 00349 gauss = x_gauss*y_gauss*z_gauss; 00350 00351 m = mat; r = row; c = col; 00352 h->elts[ m ][ r ][ c ] = gauss; 00353 00354 m = mat; r = row; c = num_cols-col-1; 00355 h->elts[ m ][ r ][ c ] = gauss; 00356 00357 m = mat; r = num_rows-row-1; c = col; 00358 h->elts[ m ][ r ][ c ] = gauss; 00359 00360 m = mat; r = num_rows-row-1; c = num_cols-col-1; 00361 h->elts[ m ][ r ][ c ] = gauss; 00362 00363 m = num_mats-mat-1; r = row; c = col; 00364 h->elts[ m ][ r ][ c ] = gauss; 00365 00366 m = num_mats-mat-1; r = row; c = num_cols-col-1; 00367 h->elts[ m ][ r ][ c ] = gauss; 00368 00369 m = num_mats-mat-1; r = num_rows-row-1; c = col; 00370 h->elts[ m ][ r ][ c ] = gauss; 00371 00372 m = num_mats-mat-1; r = num_rows-row-1; c = num_cols-col-1; 00373 h->elts[ m ][ r ][ c ] = gauss; 00374 } 00375 } 00376 } 00377 #else 00378 for (mat = 0; mat < ceil(0.5*num_mats); mat++) 00379 { 00380 z = (ceil(0.5*num_mats) - mat - 1); 00381 z_gauss = gaussian_pdf_d(0, row_sigma, z+0.5); 00382 for (row = 0; row < ceil(0.5*num_rows); row++) 00383 { 00384 y = (ceil(0.5*num_rows) - row - 1); 00385 y_gauss = gaussian_pdf_d(0, row_sigma, y+0.5); 00386 for (col = 0; col < ceil(0.5*num_cols); col++) 00387 { 00388 x = (ceil(0.5*num_cols) - col - 1); 00389 x_gauss = gaussian_pdf_d(0, col_sigma, x+0.5); 00390 gauss = x_gauss*y_gauss*z_gauss; 00391 00392 m = mat; r = row; c = col; 00393 h->elts[ m ][ r ][ c ] = gauss; 00394 00395 m = mat; r = row; c = num_cols-col-1; 00396 h->elts[ m ][ r ][ c ] = gauss; 00397 00398 m = mat; r = num_rows-row-1; c = col; 00399 h->elts[ m ][ r ][ c ] = gauss; 00400 00401 m = mat; r = num_rows-row-1; c = num_cols-col-1; 00402 h->elts[ m ][ r ][ c ] = gauss; 00403 00404 m = num_mats-mat-1; r = row; c = col; 00405 h->elts[ m ][ r ][ c ] = gauss; 00406 00407 m = num_mats-mat-1; r = row; c = num_cols-col-1; 00408 h->elts[ m ][ r ][ c ] = gauss; 00409 00410 m = num_mats-mat-1; r = num_rows-row-1; c = col; 00411 h->elts[ m ][ r ][ c ] = gauss; 00412 00413 m = num_mats-mat-1; r = num_rows-row-1; c = num_cols-col-1; 00414 h->elts[ m ][ r ][ c ] = gauss; 00415 } 00416 } 00417 } 00418 #endif 00419 00420 return NULL; 00421 } 00422 00453 Error* create_auto_3d_gaussian_dx_filter_f 00454 ( 00455 Matblock_f** h_out, 00456 float mat_sigma, 00457 float row_sigma, 00458 float col_sigma 00459 ) 00460 { 00461 uint32_t num_mats, num_rows, num_cols; 00462 00463 if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++; 00464 if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++; 00465 if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++; 00466 00467 return create_3d_gaussian_dx_filter_f(h_out, mat_sigma, row_sigma, 00468 col_sigma, num_mats, num_rows, num_cols); 00469 } 00470 00489 Error* create_auto_3d_gaussian_dx_filter_d 00490 ( 00491 Matblock_d** h_out, 00492 double mat_sigma, 00493 double row_sigma, 00494 double col_sigma 00495 ) 00496 { 00497 uint32_t num_mats, num_rows, num_cols; 00498 00499 if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++; 00500 if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++; 00501 if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++; 00502 00503 return create_3d_gaussian_dx_filter_d(h_out, mat_sigma, row_sigma, 00504 col_sigma, num_mats, num_rows, num_cols); 00505 } 00506 00538 Error* create_3d_gaussian_dx_filter_f 00539 ( 00540 Matblock_f** h_out, 00541 float mat_sigma, 00542 float row_sigma, 00543 float col_sigma, 00544 uint32_t num_mats, 00545 uint32_t num_rows, 00546 uint32_t num_cols 00547 ) 00548 { 00549 int64_t mat, row, col; 00550 int64_t mats_center; 00551 int64_t rows_center; 00552 int64_t cols_center; 00553 00554 float inv_mat_sigma_sqr; 00555 float inv_row_sigma_sqr; 00556 float inv_col_sigma_sqr; 00557 float gauss_val; 00558 float val; 00559 00560 Matblock_f* h; 00561 00562 if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01) 00563 { 00564 return JWSC_EARG("Sigma for Gaussian is too small"); 00565 } 00566 00567 create_matblock_f(h_out, num_mats, num_rows, num_cols); 00568 h = *h_out; 00569 00570 mats_center = num_mats / 2; 00571 rows_center = num_rows / 2; 00572 cols_center = num_cols / 2; 00573 inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma); 00574 inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma); 00575 inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma); 00576 00577 for (mat = 0; mat < num_mats; mat++) 00578 { 00579 for (row = 0; row < num_rows; row++) 00580 { 00581 for (col = 0; col < num_cols; col++) 00582 { 00583 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr + 00584 (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 00585 (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr; 00586 gauss_val = -1*(col - cols_center)*exp(-0.5 * val); 00587 h->elts[ mat ][ row ][ col ] = gauss_val; 00588 } 00589 } 00590 } 00591 00592 val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI); 00593 multiply_matblock_by_scalar_f(h_out, h, val); 00594 00595 return NULL; 00596 } 00597 00617 Error* create_3d_gaussian_dx_filter_d 00618 ( 00619 Matblock_d** h_out, 00620 double mat_sigma, 00621 double row_sigma, 00622 double col_sigma, 00623 uint32_t num_mats, 00624 uint32_t num_rows, 00625 uint32_t num_cols 00626 ) 00627 { 00628 int64_t mat, row, col; 00629 int64_t mats_center; 00630 int64_t rows_center; 00631 int64_t cols_center; 00632 00633 double inv_mat_sigma_sqr; 00634 double inv_row_sigma_sqr; 00635 double inv_col_sigma_sqr; 00636 double gauss_val; 00637 double val; 00638 00639 Matblock_d* h; 00640 00641 if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01) 00642 { 00643 return JWSC_EARG("Sigma for Gaussian is too small"); 00644 } 00645 00646 create_matblock_d(h_out, num_mats, num_rows, num_cols); 00647 h = *h_out; 00648 00649 mats_center = num_mats / 2; 00650 rows_center = num_rows / 2; 00651 cols_center = num_cols / 2; 00652 inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma); 00653 inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma); 00654 inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma); 00655 00656 for (mat = 0; mat < num_mats; mat++) 00657 { 00658 for (row = 0; row < num_rows; row++) 00659 { 00660 for (col = 0; col < num_cols; col++) 00661 { 00662 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr + 00663 (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 00664 (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr; 00665 gauss_val = -1*(col - cols_center)*exp(-0.5 * val); 00666 h->elts[ mat ][ row ][ col ] = gauss_val; 00667 } 00668 } 00669 } 00670 00671 val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI); 00672 multiply_matblock_by_scalar_d(h_out, h, val); 00673 00674 return NULL; 00675 } 00676 00707 Error* create_auto_3d_gaussian_dy_filter_f 00708 ( 00709 Matblock_f** h_out, 00710 float mat_sigma, 00711 float row_sigma, 00712 float col_sigma 00713 ) 00714 { 00715 uint32_t num_mats, num_rows, num_cols; 00716 00717 if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++; 00718 if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++; 00719 if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++; 00720 00721 return create_3d_gaussian_dy_filter_f(h_out, mat_sigma, row_sigma, 00722 col_sigma, num_mats, num_rows, num_cols); 00723 } 00724 00742 Error* create_auto_3d_gaussian_dy_filter_d 00743 ( 00744 Matblock_d** h_out, 00745 double mat_sigma, 00746 double row_sigma, 00747 double col_sigma 00748 ) 00749 { 00750 uint32_t num_mats, num_rows, num_cols; 00751 00752 if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++; 00753 if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++; 00754 if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++; 00755 00756 return create_3d_gaussian_dy_filter_d(h_out, mat_sigma, row_sigma, 00757 col_sigma, num_mats, num_rows, num_cols); 00758 } 00759 00791 Error* create_3d_gaussian_dy_filter_f 00792 ( 00793 Matblock_f** h_out, 00794 float mat_sigma, 00795 float row_sigma, 00796 float col_sigma, 00797 uint32_t num_mats, 00798 uint32_t num_rows, 00799 uint32_t num_cols 00800 ) 00801 { 00802 int64_t mat, row, col; 00803 int64_t mats_center; 00804 int64_t rows_center; 00805 int64_t cols_center; 00806 00807 float inv_mat_sigma_sqr; 00808 float inv_row_sigma_sqr; 00809 float inv_col_sigma_sqr; 00810 float gauss_val; 00811 float val; 00812 00813 Matblock_f* h; 00814 00815 if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01) 00816 { 00817 return JWSC_EARG("Sigma for Gaussian is too small"); 00818 } 00819 00820 create_matblock_f(h_out, num_mats, num_rows, num_cols); 00821 h = *h_out; 00822 00823 mats_center = num_mats / 2; 00824 rows_center = num_rows / 2; 00825 cols_center = num_cols / 2; 00826 inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma); 00827 inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma); 00828 inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma); 00829 00830 for (mat = 0; mat < num_mats; mat++) 00831 { 00832 for (row = 0; row < num_rows; row++) 00833 { 00834 for (col = 0; col < num_cols; col++) 00835 { 00836 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr + 00837 (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 00838 (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr; 00839 gauss_val = -1*(row - rows_center)*exp(-0.5 * val); 00840 h->elts[ mat ][ row ][ col ] = gauss_val; 00841 } 00842 } 00843 } 00844 00845 val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI); 00846 multiply_matblock_by_scalar_f(h_out, h, val); 00847 00848 return NULL; 00849 } 00850 00870 Error* create_3d_gaussian_dy_filter_d 00871 ( 00872 Matblock_d** h_out, 00873 double mat_sigma, 00874 double row_sigma, 00875 double col_sigma, 00876 uint32_t num_mats, 00877 uint32_t num_rows, 00878 uint32_t num_cols 00879 ) 00880 { 00881 int64_t mat, row, col; 00882 int64_t mats_center; 00883 int64_t rows_center; 00884 int64_t cols_center; 00885 00886 double inv_mat_sigma_sqr; 00887 double inv_row_sigma_sqr; 00888 double inv_col_sigma_sqr; 00889 double gauss_val; 00890 double val; 00891 00892 Matblock_d* h; 00893 00894 if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01) 00895 { 00896 return JWSC_EARG("Sigma for Gaussian is too small"); 00897 } 00898 00899 create_matblock_d(h_out, num_mats, num_rows, num_cols); 00900 h = *h_out; 00901 00902 mats_center = num_mats / 2; 00903 rows_center = num_rows / 2; 00904 cols_center = num_cols / 2; 00905 inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma); 00906 inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma); 00907 inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma); 00908 00909 for (mat = 0; mat < num_mats; mat++) 00910 { 00911 for (row = 0; row < num_rows; row++) 00912 { 00913 for (col = 0; col < num_cols; col++) 00914 { 00915 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr + 00916 (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 00917 (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr; 00918 gauss_val = -1*(row - rows_center)*exp(-0.5 * val); 00919 h->elts[ mat ][ row ][ col ] = gauss_val; 00920 } 00921 } 00922 } 00923 00924 val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI); 00925 multiply_matblock_by_scalar_d(h_out, h, val); 00926 00927 return NULL; 00928 } 00929 00960 Error* create_auto_3d_gaussian_dz_filter_f 00961 ( 00962 Matblock_f** h_out, 00963 float mat_sigma, 00964 float row_sigma, 00965 float col_sigma 00966 ) 00967 { 00968 uint32_t num_mats, num_rows, num_cols; 00969 00970 if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++; 00971 if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++; 00972 if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++; 00973 00974 return create_3d_gaussian_dz_filter_f(h_out, mat_sigma, row_sigma, 00975 col_sigma, num_mats, num_rows, num_cols); 00976 } 00977 00995 Error* create_auto_3d_gaussian_dz_filter_d 00996 ( 00997 Matblock_d** h_out, 00998 double mat_sigma, 00999 double row_sigma, 01000 double col_sigma 01001 ) 01002 { 01003 uint32_t num_mats, num_rows, num_cols; 01004 01005 if ((num_mats = ceil(sqrt(2) * 6.0 * mat_sigma)) % 2 == 0) num_mats++; 01006 if ((num_rows = ceil(sqrt(2) * 6.0 * row_sigma)) % 2 == 0) num_rows++; 01007 if ((num_cols = ceil(sqrt(2) * 6.0 * col_sigma)) % 2 == 0) num_cols++; 01008 01009 return create_3d_gaussian_dz_filter_d(h_out, mat_sigma, row_sigma, 01010 col_sigma, num_mats, num_rows, num_cols); 01011 } 01012 01044 Error* create_3d_gaussian_dz_filter_f 01045 ( 01046 Matblock_f** h_out, 01047 double mat_sigma, 01048 double row_sigma, 01049 double col_sigma, 01050 uint32_t num_mats, 01051 uint32_t num_rows, 01052 uint32_t num_cols 01053 ) 01054 { 01055 int64_t mat, row, col; 01056 int64_t mats_center; 01057 int64_t rows_center; 01058 int64_t cols_center; 01059 01060 float inv_mat_sigma_sqr; 01061 float inv_row_sigma_sqr; 01062 float inv_col_sigma_sqr; 01063 float gauss_val; 01064 float val; 01065 01066 Matblock_f* h; 01067 01068 if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01) 01069 { 01070 return JWSC_EARG("Sigma for Gaussian is too small"); 01071 } 01072 01073 create_matblock_f(h_out, num_mats, num_rows, num_cols); 01074 h = *h_out; 01075 01076 mats_center = num_mats / 2; 01077 rows_center = num_rows / 2; 01078 cols_center = num_cols / 2; 01079 inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma); 01080 inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma); 01081 inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma); 01082 01083 for (mat = 0; mat < num_mats; mat++) 01084 { 01085 for (row = 0; row < num_rows; row++) 01086 { 01087 for (col = 0; col < num_cols; col++) 01088 { 01089 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr + 01090 (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 01091 (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr; 01092 gauss_val = -1*(mat - mats_center)*exp(-0.5 * val); 01093 h->elts[ mat ][ row ][ col ] = gauss_val; 01094 } 01095 } 01096 } 01097 01098 val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI); 01099 multiply_matblock_by_scalar_f(h_out, h, val); 01100 01101 return NULL; 01102 } 01103 01123 Error* create_3d_gaussian_dz_filter_d 01124 ( 01125 Matblock_d** h_out, 01126 double mat_sigma, 01127 double row_sigma, 01128 double col_sigma, 01129 uint32_t num_mats, 01130 uint32_t num_rows, 01131 uint32_t num_cols 01132 ) 01133 { 01134 int64_t mat, row, col; 01135 int64_t mats_center; 01136 int64_t rows_center; 01137 int64_t cols_center; 01138 01139 double inv_mat_sigma_sqr; 01140 double inv_row_sigma_sqr; 01141 double inv_col_sigma_sqr; 01142 double gauss_val; 01143 double val; 01144 01145 Matblock_d* h; 01146 01147 if (mat_sigma < 0.01 || row_sigma < 0.01 || col_sigma < 0.01) 01148 { 01149 return JWSC_EARG("Sigma for Gaussian is too small"); 01150 } 01151 01152 create_matblock_d(h_out, num_mats, num_rows, num_cols); 01153 h = *h_out; 01154 01155 mats_center = num_mats / 2; 01156 rows_center = num_rows / 2; 01157 cols_center = num_cols / 2; 01158 inv_mat_sigma_sqr = 1.0 / (mat_sigma*mat_sigma); 01159 inv_row_sigma_sqr = 1.0 / (row_sigma*row_sigma); 01160 inv_col_sigma_sqr = 1.0 / (col_sigma*col_sigma); 01161 01162 for (mat = 0; mat < num_mats; mat++) 01163 { 01164 for (row = 0; row < num_rows; row++) 01165 { 01166 for (col = 0; col < num_cols; col++) 01167 { 01168 val = (mat-mats_center)*(mat-mats_center)*inv_mat_sigma_sqr + 01169 (row-rows_center)*(row-rows_center)*inv_row_sigma_sqr + 01170 (col-cols_center)*(col-cols_center)*inv_col_sigma_sqr; 01171 gauss_val = -1*(mat - mats_center)*exp(-0.5 * val); 01172 h->elts[ mat ][ row ][ col ] = gauss_val; 01173 } 01174 } 01175 } 01176 01177 val = (inv_mat_sigma_sqr*inv_row_sigma_sqr*inv_col_sigma_sqr) / (2 * PI); 01178 multiply_matblock_by_scalar_d(h_out, h, val); 01179 01180 return NULL; 01181 } 01182