Sat 04 Mar 2017 02:56:09 AM UTC, comment #14:
Here is my result after trying some codes. See comment #5.
|
Thu 15 Dec 2016 12:08:58 PM UTC, comment #13:
This issue seems to be still present in Octave 4.2.0 with image 2.6.1.
(I could find none of the discussed improvements in the repos.)
|
Thu 27 Feb 2014 11:43:02 PM UTC, comment #12:
for me:
>> class(linspace(single(1), 2))
ans = single
although
>> class(linspace(1, 2, single(10)))
ans = double
both as expected, I'd say.
XD and YD may contain fractional values, so we need to check if single precision is sufficient to store these values. their maximum value is not expected to be anywhere near the maximum integer used for indexing.
|
Thu 27 Feb 2014 10:49:58 PM UTC, comment #11:
Another thought...
If you pass single arguments to a function like meshgrid, you get single outputs. But there appears to be no way to tell linspace to generate single values instead of double. Maybe we should consider an extension to Matlab so that if the final argument of linspace may be a character string, either "single" or "double" to specify the type of result that should be produced.
Would that help here?
I'm not sure why you need to use the isequal test. Are you trying to check to see whether single precision is sufficient for the given operations, or whether double is needed because of the range of values?
|
Thu 27 Feb 2014 10:38:52 PM UTC, comment #10:
Thanks John/Filipe I am not sure of the process to submit a patch but will look into. I also use imremap which also uses meshgrid. A similar fix would help there as well.
|
Thu 27 Feb 2014 09:40:54 PM UTC, comment #9:
I think the all() is unnecessary, as in Octave that is implicitly applied to the operands of the && operator.
I'm not a big fan of using clear inside functions as that operates on the symbol table. Simply assigning [] to those variables should release the memory, which I assume is what you want to do.
|
Thu 27 Feb 2014 09:12:38 PM UTC, comment #8:
Thank you for taking the time to report and test it. If you feel like, please consider submitting a patch, based on your experience. Maybe a reusable separate function would help. Thanks.
|
Thu 27 Feb 2014 08:29:41 PM UTC, comment #7:
Atleast in my test cases, I did not have to relax the tolerance so
if(all(isequalAbs(XD, XDs, eps(XDs))) ...
&& all(isequalAbs(YD, YDs, eps(YDs))))
worked. Thanks for the help. There are several other places where meshgrid is used in the image package. This could make it more useful in a memory constrained situation.
|
Thu 27 Feb 2014 08:18:02 PM UTC, comment #6:
Using eps is a great way to accomplish this. IS there a way to set the k value without having to modify the function?
|
Thu 27 Feb 2014 07:52:06 PM UTC, comment #5:
you're right, I was wrong.
although, hard coded tolerance (1e-6) is to be avoided, not least because Octave might be compiled in 64 bits.
I'd go for absolute comparison and take tol = eps(XDs):
if(all(isequalAbs(XD, XDs, k*eps(XDs))) ...
&& all(isequalAbs(YD, YDs, k*eps(YDs))))
if you need to relax the tolerance, then set k = 10.
here's a quick test showing it's viable:
|
Thu 27 Feb 2014 05:07:06 PM UTC, comment #4:
I am not sure your proposal works since it is virtually guaranteed that
all(XD == double(single(XD)))
will not be true due to differences in precision.
I believe you have to factor in what would be an acceptable tolerance for the difference. You can do that with a relative tolerance or an absolute tolerance. My preference is an absolute tolerance but I have the definition for the relative tolerance comparison in case it is useful.
Also my choice of 1e-6 as a tolerance might not be appropriate.
Since you are creating grid coordinates for an interpolation, how many significant digits are required for an accurate interpolation?
If valid, it might be applicable to other places where meshgrid is used as a method of reducing the memory footprint.
I have tested this and it seems to work correctly and is more robust than my original proposal.
XD = linspace (1, inCols, outCols);
YD = linspace (1, inRows, outRows);
XDs = single(XD);
YDs = single(YD);
%# absolute tolerance equality
isequalAbs = @(x,y,tol) (abs(x-y) <= tol );
%# relative tolerance equality
isequalRel = @(x,y,tol) ( abs(x-y) <= ( tol*max(abs(x),abs(y)) + eps) );
if(all(isequalAbs(XD, XDs, 1e-6)) && all(isequalAbs(YD, YDs, 1e-6)))
XD = XDs;
YD = YDs;
endif
clear XDs YDs
[XI, YI] = meshgrid (XD, YD);
im = imremap (im, XI, YI, method);
|
Thu 27 Feb 2014 03:48:36 PM UTC, comment #3:
the tolerance would have to be different for each value.
so yes, you could check for:
all( abs(XD - double(single(XD))) < double(eps(single(XD))) )
but I believe that's equivalent to:
all(XD == double(single(XD)))
|
Thu 27 Feb 2014 02:45:12 PM UTC, comment #2:
For the comparisons to be valid, would you need to specify a tolerance when doing the comparison?
Perhaps something like this?
XD = linspace (1, 10, 12);
YD = linspace (1, 20, 15);
XDs = single(XD);
YDs = single(YD);
%# absolute tolerance equality
isequalAbs = @(x,y,tol) (abs(x-y) <= tol );
if(all(isequalAbs(XD, XDs, 1e-6)) && all(isequalAbs(YD, YDs, 1e-6)))
%if all(XD == XDs) && all(YD == YDs)
XD = XDs;
YD = YDs;
endif
clear XDs YDs
|
Thu 27 Feb 2014 02:58:20 AM UTC, comment #1:
this seems safe to do:
can you test if it works, please.
|
Sat 22 Feb 2014 11:30:23 PM UTC, original submission:
When using imresize on larger images, I end up running out of memory. In the process of troubleshooting this, I noticed that in
imresize there is a call to meshgrid
[XI, YI] = meshgrid (linspace (1, inCols, outCols), linspace (1, inRows, outRows));
im = imremap (im, XI, YI, method);
Since the default cast for XI and YI is double, the memory footprint is very large for large images.
If the arrays XI and YI are cast as single the out of memory condition is avoided.
This is probably not the ideal solution (or even a good solution) but it dramatically reduces the memory footprint of imresize.
Ian
|