Image/2D array resampling in C - c

I am looking to implement a resampling algorithm for a 2D array(it could be grayscale image or some 2D array of floating point values).
The steps involved in this particular operation are:
Given a 2D array, I first downsample it to size of 8x8 or 16x16, using some down-sampling method(preferably with a preceeding anti-aliasing filtering).
Some nuemrical operation on this.
Then upsample it back to its original size by doing, bilinear interpolation.
As a prototype I coded it as shown below in Octave. It gives decent results. I am looking to get some reference on C implementation.
fid = fopen("anti_vig_gain_map.txt","r");
fid2 = fopen("ds_us_anti_vig_gain_map.txt","w");
for i=1:1968
for j=1:2592
map(i,j) = fscanf(fid,'%f\n',1);
end
end
%downsample
ds_map = imresize(map,[8 8],'linear');
%% some processing on ds_map
%upsample
us_map = imresize(ds_map,[1968 2592],'linear');
I tried to see the code in imresize.m but it gets complicated after sometime and could not extract C code out of it.
Any pointers to reference C code for bilinear interpolation to perform the upsampling.
Also looking to get some pointers for the the anti-aliasing filter and down-sampling method using bilinear method.

I think what you are looking for is contained in the NetPBM suite. Specifically, pamscale which handles both up and down sampling with multiple possible filtering schemes for both directions. The code is both well-written and self-contained.

Related

Using N-D interpolation with a generic rank?

I'm looking for an elegant way of useing ndgrid and interpn in a more "general" way - basically for any given size of input and not treat each rank in a separate case.
Given an N-D source data with matching N-D mesh given in a cell-array of 1D vectors for each coordinate Mesh={[x1]; [x2]; ...; [xn]} and the query/output coordinates given in the same way (QueryMesh), how do I generate the ndgrid matrices and use them in the interpn without setting a case for each dimension?
Also, if there is a better way the define the mesh - I am more than willing to change.
Here's a pretty obvious, conceptual (and NOT WORKING) schematic of what I want to get, if it wasn't clear
Mesh={linspace(0,1,10); linspace(0,4,20); ... linsapce(0,10,15)};
QueryMesh={linspace(0,1,20); linspace(0,4,40); ... linsapce(0,10,30)};
Data=... (whatever)
NewData=InterpolateGeneric(Mesh,QueryMesh,Data);
function NewData=InterpolateGeneric(Mesh,QueryMesh,Data)
InGrid=ndgrid(Mesh{:});
OutGrid=ndgrid(QueryMesh{:});
NewData=interpn(InGrid{:},Data,OutGrid{:},'linear',0.0)
end
I think what you are looking for is how to get multiple outputs from this line:
OutGrid = ndgrid(QueryMesh{:});
Since ndgrid produces as many output arrays as input arrays it receives, you can create an empty cell array in this way:
OutGrid = cell(size(QueryMesh));
Next, prove each of the elements of OutGrid as an output argument:
[OutGrid{:}] = ndgrid(QueryMesh{:});

3D interpolation methods in C (or Fortran), and comparison to Shepard's Method

I would like to interpolate a 3D scalar function f(x, y, z). I have coded up a 3D linear interpolation algorithm (http://en.wikipedia.org/wiki/Trilinear_interpolation). This was not so bad.
However, I would like something more sophisticated, e.g. 3D cubic splines. Are there any open source, easy-to-use, publicly available code for interpolating a 3D scalar? I would prefer to use C, but Fortran would be OK as well. I would like to stay away from Matlab.
I have seen similar questions asked here:
Interpolating a scalar field in a 3D space
and
What are some good libraries for 3D interpolation?
The second one was OK with Matlab, which I am not.
As for the first one, the main suggestion was Shepard's method. I am curious how accurate Shepard's method is. For instance, in the case of a uniform grid, one can apply Shepard's method only to nearby grid points, and in that case does it tend to be more accurate than linear interpolation or cubic splines? I imagine not, but wasn't 100% sure, and if in fact it is not better, then I would prefer to find code using something like splines if any such codes are available.
Take a look at Geometric Tools for Interpolation:
templated C++ for tricubic, uniform B-splines, and much more.
(einspline, a C library for B-splines in 1d 2d 3d,
seems to be dormant in 2013; the author doesn't answer emails.
Also, it's C; C++ templates would reduce code bloat for interpolating
floats, colors, vecs ...)
I haven't used either of these.
On Inverse distance weighting
a.k.a. Shepard's method, you can take any number of neighbors: in 3d, 2^3 or 3^3 or 4^3 ...
A general problem is "sagging" — see the plot in the link.
"Accuracy" of any interpolation method is really hard to measure: what's "golden",
for what class of data / what noise ?
And you have two measures, error at the data and smoothness, to trade off
— for
photo enlargement
three:
aliasing, blurring and edge halos.
There's some theory on spline interpolation of band-limited functions, but afaik none at all for IDW.
Added:
What about the
bullseye effect ?
IDW is a terrible choice in almost every case.
It assumes that all of your input data points are local minimums or maximums!
Well, IDW can have peaks above nearby data points, if there are high peaks far away.
For example in 1d,
IDW( [0 0] [1 0] [2 y] ) = y/7 at x = 1/2.
But IDW weights ~ 1 / distance may be too spiky, fall off too fast, for some tasks.
Interpolation methods and kernels have to be chosen to fit specific data and noise — an art.
The bspline-fortran library does 2d-6d b-spline interpolation for data on a regular grid. It is written in modern Fortran (there is a basic subroutine interface and also an object-oriented interface).
vspline is a FOSS C++ template library for b-spline processing. It's dimension-agnostic, so you can use it for 3D data. It's focus is on efficiently processing large raster data sets with multithreaded SIMD code. If you're concerned about precision, it can use long doubles for calculations and has extremely precise precomputed constants for maximum fidelity.

Is there a C lib to find peaks in noisy data equivalent to findPeaks.m

i have a noisy set of data and want to find the peaks in it. There is a matlab function for this exact task which includes smoothing of the data. I is called findpeaks.m
Now as im working in C i would either would have to code this by myself or use some functions which im not aware of. I hope you can tell me if they exist and where i can find them, as this is a very common problem.
To be clear what im searching of: a function to first smooth my data and then calculate the peaks, both preferably with some parameters for smoothing method, peak width etc.
Thanks!

How to know a specific value position using a Nurbs with OpenGL?

I am using OpenGL to create a nurbs surface (gluNurbSurface(...)) and I would like to know how reach the normal value to the control points(black dot) to the surface market as a red dot. With this information I will be able to calculate the distance between them.
Added
In order to get another answers or improve the subjected I would like to write part of the code, I hope can get more help:
In this part you can observe how I initialize the nurbs.
init_surface();
theNurb = gluNewNurbsRenderer();
gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 50.0);
gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
gluNurbsCallback(theNurb, GLU_ERROR,
(GLvoid (*)()) nurbsError);
Next the surface is created with their parameters.
gluBeginSurface(theNurb);
gluNurbsSurface(theNurb,
U+ordenU, knotsU,
V+ordenV, knotsV,
V * 3,
3,
&ctlpoints[0][0][0],
ordenU, ordenV,
GL_MAP2_VERTEX_3);
gluEndSurface(theNurb);
Remember I am using C. And in this moment I am trying to introduce the values of the nurbs into a vector with the function proposed by genpfault in the first answer but I do not know in which part I have to add them.
Set a GLU_NURBS_NORMAL_DATA callback via gluNurbsCallback(). A GLU_NURBS_VERTEX_DATA callback would also be useful.
Point *userData (via gluNurbsCallbackData()) at some sort of dynamic array data-structure to hold the points/normals. If you were using C++ I'd recommend a std::vector of Eigen::Vector3fs.

Recognizing tetris pieces in C

I have to make an application that recognizes inside an black and white image a piece of tetris given by the user. I read the image to analyze into an array.
How can I do something like this using C?
Assuming that you already loaded the images into arrays, what about using regular expressions?
You don't need exact shape matching but approximately, so why not give it a try!
Edit: I downloaded your doc file. You must identify a random pattern among random figures on a 2D array so regex isn't suitable for this problem, lets say that's the bad news. The good news is that your homework is not exactly image processing, and it's much easier.
It's your homework so I won't create the code for you but I can give you directions.
You need a routine that can create a new piece from the original pattern/piece rotated. (note: with piece I mean the 4x4 square - all the cells of it)
You need a routine that checks if a piece matches an area from the 2D image at position x,y - the matching area would have corners (x-2, y-2, x+1, y+1).
You search by checking every image position (x,y) for a match.
Since you must use parallelism you can create 4 threads and assign to each thread a different rotation to search.
You might not want to implement that from scratch (unless required, of course) ... I'd recommend looking for a suitable library. I've heard that OpenCV is good, but never done any work with machine vision myself so I haven't tested it.
Search for connected components (i.e. using depth-first search; you might want to avoid recursion if efficiency is an issue; use your own stack instead). The largest connected component should be your tetris piece. You can then further analyze it (using the shape, the size or some kind of border description)
Looking at the shapes given for tetris pieces in Wikipedia, called "I,J,L,O,S,T,Z", it seems that the ratios of the sides of the bounding box (easy to find given a binary image and C) reveal whether you have I (4:1) or O (1:1); the other shapes are 2:3.
To detect which of the remaining shapes you have (J,L,S,T, or Z), it looks like you could collect the length and position of the shape's edges that fall on the bounding box's edges. Thus, T would show 3 and 1 along the 3-sides, and 1 and 1 along the 2 sides. Keeping track of the positions helps distinguish J from L, S from Z.

Resources