Mercurial > hg > octave-image
changeset 874:9a76652a01f5 stable
bwdist: fix regression calculating closest-pixel map (bug #41709)
* bwdist.cc: fix regression caused with cset 4bb352ade7c7. The original code
written in C (edtfunc.c file) had variable "h" for width and "w" for height.
This was probably because the code was originally written for row-major order
and it would be easier to swap these two variables than all instances of it in
the code. This fix swaps all instances of "h" and "w" in the code. Assign
number of rows and columns to "w" and "h" respectively would accomplish the
same but may confusion again in the future. New tests were added to check
the second output argument.
* NEWS: add notice of fixing this regression for next stable release.
author | Carnë Draug <carandraug@octave.org> |
---|---|
date | Sat, 08 Mar 2014 00:26:08 +0000 |
parents | 70a4d2a10a80 |
children | 902e0462ba1a |
files | NEWS src/bwdist.cc |
diffstat | 2 files changed, 59 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS +++ b/NEWS @@ -13,6 +13,8 @@ ** Fix imrotate to handle RGB images. + ** Fix regression in bwdist when calculating the closest pixel map. + Summary of important user-visible changes for image 2.2.0 (2014/01/08): -------------------------------------------------------------------------
--- a/src/bwdist.cc +++ b/src/bwdist.cc @@ -54,14 +54,14 @@ bool changed; // Initialize index offsets for the current image width - const int offset_u = -w; - const int offset_ur = -w+1; + const int offset_u = -h; + const int offset_ur = -h+1; const int offset_r = 1; - const int offset_rd = w+1; - const int offset_d = w; - const int offset_dl = w-1; + const int offset_rd = h+1; + const int offset_d = h; + const int offset_dl = h-1; const int offset_l = -1; - const int offset_lu = -w-1; + const int offset_lu = -h-1; // Initialize the distance images to be all large values for (i = 0; i < numel; i++) @@ -84,10 +84,10 @@ changed = false; // Scan rows, except first row - for (y = 1; y < h; y++) + for (y = 1; y < w; y++) { // move index to leftmost pixel of current row - i = y*w; + i = y*h; /* scan right, propagate distances from above & left */ @@ -119,7 +119,7 @@ i++; /* Middle pixels have all neighbors */ - for(x=1; x<w-1; x++, i++) + for(x=1; x<h-1; x++, i++) { OCTAVE_QUIT; olddist2 = (*func)(distx[i], disty[i]); @@ -209,10 +209,10 @@ /* Move index to second rightmost pixel of current row. */ /* Rightmost pixel is skipped, it has no right neighbor. */ - i = y*w + w-2; + i = y*h + h-2; /* scan left, propagate distance from right */ - for(x=w-2; x>=0; x--, i--) + for(x=h-2; x>=0; x--, i--) { OCTAVE_QUIT; olddist2 = (*func)(distx[i], disty[i]); @@ -231,11 +231,11 @@ } /* Scan rows in reverse order, except last row */ - for(y=h-2; y>=0; y--) + for(y=w-2; y>=0; y--) { OCTAVE_QUIT; /* move index to rightmost pixel of current row */ - i = y*w + w-1; + i = y*h + h-1; /* Scan left, propagate distances from below & right */ @@ -267,7 +267,7 @@ i--; /* Middle pixels have all neighbors */ - for(x=w-2; x>0; x--, i--) + for(x=h-2; x>0; x--, i--) { OCTAVE_QUIT; olddist2 = (*func)(distx[i], disty[i]); @@ -356,8 +356,8 @@ /* Move index to second leftmost pixel of current row. */ /* Leftmost pixel is skipped, it has no left neighbor. */ - i = y*w + 1; - for(x=1; x<w; x++, i++) + i = y*h + 1; + for(x=1; x<h; x++, i++) { OCTAVE_QUIT; /* scan right, propagate distance from left */ @@ -549,7 +549,7 @@ } /* -%!shared bw, out +%!shared bw %! %! bw = [0 1 0 1 0 1 1 0 %! 0 0 0 1 1 0 0 0 @@ -559,7 +559,8 @@ %! 1 1 1 1 0 0 0 1 %! 1 1 1 0 0 0 1 0 %! 0 0 1 0 0 0 1 1]; -%! + +%!test %! out = [ 1.00000 0.00000 1.00000 0.00000 1.00000 0.00000 0.00000 1.00000 %! 1.41421 1.00000 1.00000 0.00000 0.00000 1.00000 1.00000 1.41421 %! 2.23607 2.00000 1.00000 0.00000 0.00000 1.00000 2.00000 2.00000 @@ -570,10 +571,11 @@ %! 1.00000 1.00000 0.00000 1.00000 2.00000 1.00000 0.00000 0.00000]; %! out = single (out); %! -%!assert (bwdist (bw), out, 0.0001); # default is euclidean -%!assert (bwdist (bw, "euclidean"), out, 0.0001); -%!assert (bwdist (logical (bw), "euclidean"), out, 0.0001); -%! +%! assert (bwdist (bw), out, 0.0001); # default is euclidean +%! assert (bwdist (bw, "euclidean"), out, 0.0001); +%! assert (bwdist (logical (bw), "euclidean"), out, 0.0001); + +%!test %! out = [ 1 0 1 0 1 0 0 1 %! 1 1 1 0 0 1 1 1 %! 2 2 1 0 0 1 2 2 @@ -584,8 +586,9 @@ %! 1 1 0 1 2 1 0 0]; %! out = single (out); %! -%!assert (bwdist (bw, "chessboard"), out); -%! +%! assert (bwdist (bw, "chessboard"), out); + +%!test %! out = [ 1 0 1 0 1 0 0 1 %! 2 1 1 0 0 1 1 2 %! 3 2 1 0 0 1 2 2 @@ -596,8 +599,9 @@ %! 1 1 0 1 2 1 0 0]; %! out = single (out); %! -%!assert (bwdist (bw, "cityblock"), out); -%! +%! assert (bwdist (bw, "cityblock"), out); + +%!test %! out = [ 1.00000 0.00000 1.00000 0.00000 1.00000 0.00000 0.00000 1.00000 %! 1.41421 1.00000 1.00000 0.00000 0.00000 1.00000 1.00000 1.41421 %! 2.41421 2.00000 1.00000 0.00000 0.00000 1.00000 2.00000 2.00000 @@ -608,12 +612,35 @@ %! 1.00000 1.00000 0.00000 1.00000 2.00000 1.00000 0.00000 0.00000]; %! out = single (out); %! -%!assert (bwdist (bw, "quasi-euclidean"), out, 0.0001); +%! assert (bwdist (bw, "quasi-euclidean"), out, 0.0001); %! %! bw(logical (bw)) = 3; # there is no actual check if matrix is binary or 0 and 1 -%!assert (bwdist (bw, "quasi-euclidean"), out, 0.0001); +%! assert (bwdist (bw, "quasi-euclidean"), out, 0.0001); +%! %! bw(logical (bw)) = -2; # anything non-zero is considered object -%!assert (bwdist (bw, "quasi-euclidean"), out, 0.0001); +%! assert (bwdist (bw, "quasi-euclidean"), out, 0.0001); + +%!test +%! bw = [ 1 1 1 1 0 1 1 1 1 +%! 1 1 1 1 0 1 1 1 1 +%! 1 1 0 1 1 1 1 1 1 +%! 0 1 1 1 1 1 1 1 1]; %! -%!error bwdist (bw, "not a valid method"); +%! dist = [ 0 0 0 0 1 0 0 0 0 +%! 0 0 0 0 1 0 0 0 0 +%! 0 0 1 0 0 0 0 0 0 +%! 1 0 0 0 0 0 0 0 0]; +%! dist = single (dist); +%! +%! c = [ 1 5 9 13 13 21 25 29 33 +%! 2 6 10 14 14 22 26 30 34 +%! 3 7 10 15 19 23 27 31 35 +%! 8 8 12 16 20 24 28 32 36]; +%! c = uint32 (c); +%! +%! [dout, cout] = bwdist (bw, "euclidean"); +%! assert (dout, dist) +%! assert (cout, c) + +%!error <unknown METHOD> bwdist (bw, "not a valid method"); */