Changeset 4322 for trunk/psModules/src/pmImageSubtract.c
- Timestamp:
- Jun 20, 2005, 1:21:05 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/pmImageSubtract.c (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/pmImageSubtract.c
r4223 r4322 1 1 /** @file ImageSubtract.c 2 * 3 * This file will ... 4 * 5 * @author Paul Price, IfA (original prototype) 6 * @author GLG, MHPCC 7 * 8 * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2005-06-13 20:09:53 $ 10 * 11 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 12 * 13 * XXX: sync with iFa on this: 14 * The (x, y) (row, col) issue is becoming a problem. In this file, and I 15 * think, the rest of psLib and psModules, the following conventions are used: 16 * 17 * 1) x will correspond to the column, and y will correspond to the row. 18 * 2) When used in function prototypes, the column (and hence x) appears 19 * first. 20 * 3) When used to index 2-D arrays, obviously, the row (and hence, y) 21 * appears first. (2 and 3 are the source of confusion). 22 * 4) When (u, v) are used in certain structures. 23 * u corresponds to x 24 * v corresponds to y 25 * 5) When element (a, b) is casually referred to in comments, or 26 * documentation it is unclear where a is the row, or the column. 27 * 6) A convention on loop index variables (i, j) would be convenient. 28 * Currently, sometimes i corresponds to the column (x), 29 * usually it corresponds to the row (y). 30 * 31 */ 2 * 3 * This file will ... 4 * 5 * @author Paul Price, IfA (original prototype) 6 * @author GLG, MHPCC 7 * 8 * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2005-06-20 23:21:05 $ 10 * 11 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 12 * 13 * XXX: sync with iFa on this: 14 * The (x, y) (row, col) issue is becoming a problem. In this file, and I 15 * think, the rest of psLib and psModules, the following conventions are used: 16 * 17 * 1) x will correspond to the column, and y will correspond to the row. 18 * 2) When used in function prototypes, the column (and hence x) appears 19 * first. 20 * 3) When used to index 2-D arrays, obviously, the row (and hence, y) 21 * appears first. (2 and 3 are the source of confusion). 22 * 4) When (u, v) are used in certain structures. 23 * u corresponds to x 24 * v corresponds to y 25 * 5) When element (a, b) is casually referred to in comments, or 26 * documentation it is unclear where a is the row, or the column. 27 * 6) A convention on loop index variables (i, j) would be convenient. 28 * Currently, sometimes i corresponds to the column (x), 29 * usually it corresponds to the row (y). 30 * 31 * XXX: The following variables are used an interpreted this way: 32 * kernelSize: Means that the actual kernel is a square (1 + 2 * kernelSize) per side. 33 * border: When accessing an image, a swath of pixels this wide is ignored. 34 * footprint: When accessing a stample, a square of pixels, footprint pixels per side, 35 * are looked at. We must ensure that (footprint+kernelSize) pixels exist 36 * around the center. 37 */ 32 38 33 39 #include<stdio.h> … … 60 66 pmStamp *stamp = (pmStamp*)psAlloc(sizeof(pmStamp)); 61 67 stamp->x = 0; 68 stamp->p_xSize = 0; 62 69 stamp->y = 0; 70 stamp->p_ySize = 0; 63 71 stamp->matrix = NULL; 64 72 stamp->vector = NULL; … … 311 319 psS32 xNum, ///< Number of stamps in x 312 320 psS32 yNum, ///< Number of stamps in y 313 psS32 border ///< Border around image to ignore (should be size of kernel )321 psS32 border ///< Border around image to ignore (should be size of kernel or larger) 314 322 ) 315 323 { … … 351 359 // Iterate over the image sections 352 360 // 361 // XXX: Must handle cases where image size is not an even multiple of xNum or yNum 362 // 353 363 psS32 num = 0; 354 364 for (psS32 j = 0; j < yNum; j++) { 355 365 for (psS32 i = 0; i < xNum; i++) { 356 366 pmStamp *stamp = (pmStamp *) stamps->data[num]; 357 358 367 // 359 368 // Only find a new stamp if we need to … … 376 385 psS32 numX = xNum; 377 386 psS32 numY = yNum; 378 for (psS32 y = border + j * (numCols - 2.0 * border) / numY; 379 y < border + (j + 1) * (numCols - 2.0 * border) / numY; y++) { 380 for (psS32 x = border + i * (numRows - 2.0 * border) / numX; 381 x < border + (i + 1) * (numRows - 2.0 * border) / numX; x++) { 382 383 // Determine if this pixel is larger than the max, and unmasked. 384 if (image->data.F32[y][x] > max) { 385 if ((mask == NULL) || !((mask->data.U8[y][x]) & maskVal)) { 386 max = image->data.F32[y][x]; 387 bestx = x; 388 besty = y; 387 psS32 yMin = border + j * (numCols - 2.0 * border) / numY; 388 psS32 yMax = (border + (j + 1) * (numCols - 2.0 * border) / numY) - 1; 389 psS32 xMin = border + i * (numRows - 2.0 * border) / numX; 390 psS32 xMax = (border + (i + 1) * (numRows - 2.0 * border) / numX) - 1; 391 392 if ((yMax >= image->numRows) || 393 (xMax >= image->numCols) || 394 (yMin < 0) || 395 (xMin < 0)) { 396 // XXX: We skip this stamp since its borders extends beyond the image. 397 // XXX: This is here mainly as a safeguard. We need to redefine the above 398 // min/max pixels calculation to ensure that all stamps are legitimate. 399 400 stamp->x = -1; 401 stamp->y = -1; 402 stamp->status = PM_STAMP_NONE; 403 } else { 404 stamp->p_xSize = 1 + (xMax - xMin); 405 stamp->p_ySize = 1 + (yMax - yMin); 406 stamp->p_xMin = xMin; 407 stamp->p_xMax = xMax; 408 stamp->p_yMin = yMin; 409 stamp->p_yMax = yMax; 410 411 for (psS32 y = yMin; y <= yMax ; y++) { 412 for (psS32 x = xMin; x <= xMax ; x++) { 413 // Determine if this pixel is larger than the max, and unmasked. 414 if (image->data.F32[y][x] > max) { 415 if ((mask == NULL) || !((mask->data.U8[y][x]) & maskVal)) { 416 max = image->data.F32[y][x]; 417 bestx = x; 418 besty = y; 419 } 389 420 } 390 421 } 391 422 } 392 } 393 394 //395 // If the max pixel is larger than the threshold, we keep this stamp.396 // Otherwise, mark the stamp as PM_STAMP_NONE397 //398 if (image->data.F32[besty][bestx] >= threshold) {399 stamp->x = bestx;400 stamp->y = besty;401 stamp->status = PM_STAMP_RECALC;402 } else {403 stamp->x = bestx;404 stamp->y = besty;405 stamp->status = PM_STAMP_NONE;423 424 // 425 // If the max pixel is larger than the threshold, we keep this stamp. 426 // Otherwise, mark the stamp as PM_STAMP_NONE 427 // 428 if (image->data.F32[besty][bestx] >= threshold) { 429 stamp->x = bestx; 430 stamp->y = besty; 431 stamp->status = PM_STAMP_RECALC; 432 } else { 433 stamp->x = bestx; 434 stamp->y = besty; 435 stamp->status = PM_STAMP_NONE; 436 } 406 437 } 407 438 } … … 472 503 for (psS32 yy = -kernelSize ; yy < kernelSize ; yy++) { 473 504 for (psS32 xx = -kernelSize ; xx < kernelSize ; xx++) { 474 //printf("HERE: (%d, %d)\n", yy, xx);475 //printf("HERE: (%d, %d)\n", yy+row, xx+col);476 //printf("HERE: (%d, %d)\n", yy-kernelSize, xx-kernelSize);477 //printf("KERNEL SIZE is %d\n", kernelSize);478 505 conv += input->data.F32[yy+row][xx+col] * 479 506 preCalc->data.F32[yy+kernelSize][xx+kernelSize] * … … 513 540 PS_ASSERT_VECTORS_SIZE_EQUAL(kernels->u, kernels->preCalc, false); 514 541 } 542 psS32 kernelSize = kernels->p_size; 515 543 PS_ASSERT_INT_NONNEGATIVE(footprint, false); 544 // 545 // For each legitimate stamp, ensure that the footprint is small enough to perform 546 // the full calculation. 547 // 548 // XXX: Verify with IfA that this is a reasonable action. 549 // 550 for (psS32 s = 0; s < stamps->n; s++) { 551 pmStamp *stamp = (pmStamp *) stamps->data[s]; 552 if (stamp->status == PM_STAMP_RECALC) { 553 // XXX: trace message 554 // printf("stamp %d (x, y) is (%d, %d). Footprint is %d. kernelSize is %d.\n", s, stamp->x, stamp->y, footprint, kernelSize); 555 if (((stamp->y - (footprint + kernelSize)) < 0) || 556 ((stamp->x - (footprint + kernelSize)) < 0) || 557 ((stamp->y + footprint + kernelSize) >= input->numRows) || 558 ((stamp->x + footprint + kernelSize) >= input->numCols)) { 559 stamp->status = PM_STAMP_NONE; 560 psLogMsg(__func__, PS_LOG_WARN, 561 "WARNING: stamp %d will be ignored. It exceeds image size: access columns (%d to %d) and rows (%d to %d)\n", 562 s, 563 stamp->x - (footprint + kernelSize), 564 (stamp->x + footprint + kernelSize) - 1, 565 stamp->y - (footprint + kernelSize), 566 (stamp->y + footprint + kernelSize) - 1); 567 } 568 } 569 } 570 516 571 psS32 numHalfRows = reference->numRows; 517 572 psS32 numHalfCols = reference->numCols; … … 567 622 568 623 psTrace("pmSubtractionCalculateEquation", 5, "subCalcEqn(): stamp %d: generated spatial order terms.\n", s); 624 569 625 // 570 626 // Iterate over all pixels surrounding this stamp. … … 572 628 for (psS32 y = stamp->y - footprint; y < stamp->y + footprint; y++) { 573 629 for (psS32 x = stamp->x - footprint; x < stamp->x + footprint; x++) { 630 574 631 psF32 invNoise2 = 1.0/reference->data.F32[y][x]; // The inverse of the noise, squared. 575 632 … … 617 674 // testing, depending on kernel size and footprint. 618 675 // 619 //printf("footprint is %d\n", footprint);620 //printf("Stamp (%d, %d).\n", stamp->y, stamp->x);621 //printf("HERE (y, x) is (%d, %d). (v2, u2) is (%d, %d).\n", y, x, v2, u2);622 //printf("HERE 00 (%d %d) (%d %d)\n", j2, i2, y-v2, x-u2);623 //624 676 // Second convolution 625 677 // 626 678 psF32 conv2 = polyValues->data.F64[j2][i2] * 627 679 reference->data.F32[y-v2][x-u2]; 628 629 680 // 630 681 // Assuming that the first kernel component is 0 order in x and y, and 0 offset … … 656 707 657 708 } else if (kernels->type == PM_SUBTRACTION_KERNEL_ISIS) { 658 // printf("XXX: put some warning message here (ISIS kernels not implemented).\n");659 // return(false);660 // XXX: HEY: code this661 709 for (psS32 k1 = 0; k1 < numKernels; k1++) { 662 710 psF32 conv1 = GeneralKernelConvolve(reference, kernels, k1, x, y); 663 711 664 712 for (psS32 k2 = k1; k2 < numKernels; k2++) { 713 //printf("(k1, k2) is (%d, %d)\n", k1, k2); 665 714 psF32 conv2 = GeneralKernelConvolve(reference, kernels, k2, x, y); 666 667 715 stampMatrix->data.F64[k1][k2] += conv1 * conv2 * invNoise2; 668 669 716 } 670 717 stampVector->data.F64[k1] += input->data.F32[y][x] * conv1 * invNoise2; … … 705 752 } 706 753 stamp->status = PM_STAMP_USED; 754 } else { 755 // Stamp is ignored since it's not PM_STAMP_RECALC 707 756 } 708 757 } … … 721 770 { 722 771 PS_ASSERT_PTR_NON_NULL(stamps, NULL); 723 PS_ASSERT_IMAGE_NON_NULL(((pmStamp *) stamps->data[0])->matrix, NULL); 724 PS_ASSERT_VECTOR_NON_NULL(((pmStamp *) stamps->data[0])->vector, NULL); 725 psS32 size = ((pmStamp *) stamps->data[0])->vector->n; 772 psS32 size = -1; 773 psS32 s = 0; 774 775 // 776 // Determine the size of the stamp vectors and matrix. 777 // We iterate until we find the first acceptable stamp. 778 // 779 while ((size == -1) && (s < stamps->n)) { 780 pmStamp *stamp = (pmStamp *) stamps->data[s]; 781 PS_ASSERT_PTR_NON_NULL(stamp, NULL); 782 if (stamp->status == PM_STAMP_USED) { 783 size = ((pmStamp *) stamps->data[s])->vector->n; 784 PS_ASSERT_INT_POSITIVE(size, NULL); 785 } 786 s++; 787 } 788 if (size == -1) { 789 psLogMsg(__func__, PS_LOG_WARN, "WARNING: no acceptable stamps. Returning NULL\n"); 790 return(NULL); 791 } 726 792 727 793 if (solution != NULL) { … … 732 798 } 733 799 800 // 801 // Create the solution matrix and vector. 802 // 803 // XXX: Test these functions with size=-1. This caused seg faults during test. 804 // 734 805 psImage *sumMatrix = psImageAlloc(size, size, PS_TYPE_F64); 735 806 psVector *sumVector = psVectorAlloc(size, PS_TYPE_F64); … … 737 808 PS_IMAGE_SET_F64(sumMatrix, 0.0); 738 809 810 // 811 // Verify that all stamps have similar sizes. 812 // Compute the sum matrix and vector. 813 // 739 814 for (psS32 s = 0; s < stamps->n; s++) { 740 815 pmStamp *stamp = (pmStamp *) stamps->data[s]; 741 psImage *stampMatrix = stamp->matrix;742 psVector *stampVector = stamp->vector;743 744 PS_ASSERT_VECTOR_TYPE(stampVector, PS_TYPE_F64, NULL);745 PS_ASSERT_VECTOR_SIZE(stampVector, size, NULL);746 PS_ASSERT_IMAGE_TYPE(stampMatrix, PS_TYPE_F64, NULL);747 PS_ASSERT_IMAGE_SIZE(stampMatrix, size, size, NULL);748 816 749 817 if (stamp->status == PM_STAMP_USED) { 818 PS_ASSERT_INT_EQUAL(((pmStamp *) stamps->data[s])->vector->n, size, NULL); 819 820 psImage *stampMatrix = stamp->matrix; 821 psVector *stampVector = stamp->vector; 822 PS_ASSERT_VECTOR_TYPE(stampVector, PS_TYPE_F64, NULL); 823 PS_ASSERT_VECTOR_SIZE(stampVector, size, NULL); 824 PS_ASSERT_IMAGE_TYPE(stampMatrix, PS_TYPE_F64, NULL); 825 PS_ASSERT_IMAGE_SIZE(stampMatrix, size, size, NULL); 826 750 827 (void)psBinaryOp(sumMatrix, sumMatrix, "+", stampMatrix); 751 828 (void)psBinaryOp(sumVector, sumVector, "+", stampVector); … … 753 830 } 754 831 832 // XXX: Check output from these routines. 755 833 psVector *permutation = NULL; 756 834 psImage *luMatrix = psMatrixLUD(NULL, &permutation, sumMatrix); … … 930 1008 solution, kernels, x, y); 931 1009 } else { 932 p rintf("XXX: Generate WARNING: unknown kernel type\n");1010 psLogMsg(__func__, PS_LOG_WARN, "WARNING: unknown kernel type. Returning NULL\n"); 933 1011 return(NULL); 934 1012 } … … 1022 1100 psS32 y = stamp->y; // Stamp y coord 1023 1101 if (stamp->status == PM_STAMP_USED) { 1102 1024 1103 psRegion myReg = psRegionSet(x - xSize, x + xSize, y - ySize, y + ySize); 1025 1104 psImage *refStamp = psImageSubset((psImage *) refImage, myReg); … … 1182 1261 if (out != NULL) { 1183 1262 if ((out->numCols < (1+2*kernelSize)) || (out->numRows < (1+2*kernelSize))) { 1184 p rintf("XXX: generateWARNING: out image is not large enough.\n");1263 psLogMsg(__func__, PS_LOG_WARN, "WARNING: out image is not large enough.\n"); 1185 1264 return(out); 1186 1265 } … … 1222 1301 psS32 xOrder = (psS32) kernels->xOrder->data.F32[k]; 1223 1302 psS32 yOrder = (psS32) kernels->yOrder->data.F32[k]; 1224 psF32 polyVal = polyValues->data.F32[yOrder][xOrder];1225 1303 // XXX: Verify that this is correct. 1226 1304 1227 1305 out->data.F32[kernelSize - v][kernelSize - u]+= 1228 solution->data.F64[k] * 1229 polyValues->data.F64[yOrder][xOrder] * 1230 polyVal; 1231 polyVal = polyVal; 1306 solution->data.F64[k] * polyValues->data.F32[yOrder][xOrder]; 1232 1307 } 1233 1308 }
Note:
See TracChangeset
for help on using the changeset viewer.
