Pixel movement C++ - pixel

This may or may not be a very stupid question so I do apologise, but I haven't come across this in any books or tutorials as yet. Also I guess it can apply to any language...
Assume you create a window of size: 640x480 and an object/shape inside it of size 32x32 and you're able to move the shape around the window with keyboard inputs.
Does it matter what Type (int, float...) you use to control the movement of the shape. Obviously you can not draw halfway through a pixel, but if you move the shape by 0.1f (for example with a glTranslation function) what happens as supposed to moving it by an int of 1... Does it move the rendered shape by 1/10 of a pixel or?
I hope I've explained that well enough not to be laughed at.
I only ask this because it can affect the precision of collision detection and other functions of a program or potential game.

glTranslate produces a translation by x y z . The current matrix (glMatrixMode) is multiplied by this translation matrix, with the product replacing the current matrix, as if glMultMatrix were called with the following matrix for its argument:
1 0 0 x 0 1 0 y 0 0 1 z 0 0 0 1
If the matrix mode is either GL_MODELVIEW or GL_PROJECTION, all objects drawn after a call to glTranslate are translated.
Use glPushMatrix and glPopMatrix to save and restore the untranslated coordinate system.
This meaning that glTranslate will give you a translation, to use with the current matrix, resulting in non decimal numbers. You can not use half a pixel. glTranslate receives either doubles or floats, so if you are supposed to move it 1 in x,y or z, just give the function a float 1 or double 1 as an argument.
http://www.opengl.org/sdk/docs/man2/xhtml/glTranslate.xml

The most important reason for using floats or doubles to represent positioning is the background calculation. If u keep calculating your position with ints not only do you have to probably use conversion steps to get back to ints. You will also lose data every x amount of steps

if you want to animate you sprite to have anything less than 1 pixel movement per update then YES you need to use floating point, otherwise you will get no movement. your drawing function would most likely round to the nearest integer so it's probably not relevant for that. however you can of course draw to sub pixel accuracy!

Related

MATLAB image processing technique

I have this 3D array in MATLAB (V: vertical, H: horizontal, t: time frame)
Figures below represent images obtained using imagesc function after slicing the array in terms of t axis
area in black represents damage area and other area is intact
each frame looks similar but has different amplitude
I am trying to visualize only defect area and get rid of intact area
I tried to use 'threshold' method to get rid of intact area as below
NewSet = zeros(450,450,200);
for kk = 1:200
frame = uwpi(:,:,kk);
STD = std(frame(:));
Mean = mean(frame(:));
for ii = 1:450
for jj =1:450
if frame(ii, jj) > 2*STD+Mean
NewSet(ii, jj, kk) = frame(ii, jj);
else
NewSet(ii, jj, kk) = NaN;
end
end
end
end
However, since each frame has different amplitude, result becomes
Is there any image processing method to get rid of intact area in this case?
Thanks in advance
You're thresholding based on mean and standard deviation, basically assuming your data is normally distributed and looking for outliers. But your model should try to distinguish values around zero (noise) vs higher values. Your data is not normally distributed, mean and standard deviation are not meaningful.
Look up Otsu thresholding (MATLAB IP toolbox has it). It's model does not perfectly match your data, but it might give reasonable results. Like most threshold estimation algorithms, it uses the image's histogram to determine the optimal threshold given some model.
Ideally you'd model the background peak in the histogram. You can find the mode, fit a Gaussian around it, then cut off at 2 sigma. Or you can use the "triangle method", which finds the point along the histogram that is furthest from the line between the upper end of the histogram and the top of the background peak. A little more complex to explain, but trivial to implement. We have this implemented in DIPimage (http://www.diplib.org), M-file code is visible so you can see how it works (look for the function threshold)
Additionally, I'd suggest to get rid of the loops over x and y. You can type frame(frame<threshold) = nan, and then copy the whole frame back into NewSet in one operation.
Do I clearly understand the question, ROI is the dark border and all it surrounds? If so I'd recommend process in 3D using some kind of region-growing technique like watershed or active snakes with markers by imregionalmin. The methods should provide segmentation result even if the border has small holes. Than just copy segmented object to a new 3D array via logic indexing.

Average over a 3x3x3 voxel in a 192x192x24 volume

I am processing image files with measured intensity, basically extracting voxels in sizes of 1x1x1 pixels. The image files are forming a volume to avoid peak intensities. I would like find a way to average over 3x3x3 pixel.
My problem is to get my head around the problem, because it is a shape within the image separated by zeros and other values. So, first of I considered a for-loop with a if-statement. These are the considerations I have made so far for the for-loop and if-statement. MATLAB perceives the volume as a long matrix so by a simple for loop it should be easy to find a non-zero value and its adjacent values, and take the average over those values. The problem comes when I have to take the z dimension into account.
This is clearly not working optimal, and I find it hard to account for the boundary effects.
I hope I'm interpreting your question right, but you want to find the average over a 3 x 3 x 3 voxel volume for each voxel in the input image where each input voxel acts as the centre of each 3 x 3 x 3 voxel volume to be averaged. If you have the option of using MATLAB's built-in functions, consider using N-D convolution with convn. Don't use loops here because it will be notoriously slow. For convn, the first parameter is the 3D image, and the second parameter is a 3 x 3 x 3 kernel with values all equal to 1/27. You also have the option of specifying what happens along the border should your convolution kernel go beyond the limits of the input image. Usually, you want to return an output image that's the same size as the input and so you may want to specify the 'same' flag as the third optional parameter. This averaging mechanism also assumes that the outer edges are zero-padded.
Therefore, supposing your image is stored in im, do something like this:
%// Create kernel of all 1/27 in a 3 x 3 x 3 matrix
kernel = ones(3,3,3);
kernel = kernel / numel(kernel);
%// Perform N-D convolution
out = convn(double(im), kernel, 'same'); %// Cast to double for precision
out = cast(out, class(im)); %// Recast back to original data type
Alternatively, if you have access to the image processing toolbox, use imfilter instead. The difference with this and convn is that imfilter was written using Intel Integrated Performance Primitives (IIPP), and so performance will definitely be faster:
%// Create kernel of all 1/27 in a 3 x 3 x 3 matrix
kernel = ones(3,3,3);
kernel = kernel / numel(kernel);
%// Perform N-D convolution
out = imfilter(im, kernel);
The added bonus is that you aren't required to change the input type. imfilter automatically infers this, does the processing respecting the input image's original type and the output type of imfilter is the same as the input type. With convn, you must ensure that your data is floating-point before using it.

Detecting individual images in an array of images

I'm building a photographic film scanner. The electronic hardware is done now I have to finish the mechanical advance mechanism then I'm almost done.
I'm using a line scan sensor so it's one pixel width by 2000 height. The data stream I will be sending to the PC over USB with a FTDI FIFO bridge will be just 1 byte values of the pixels. The scanner will pull through an entire strip of 36 frames so I will end up scanning the entire strip. For the beginning I'm willing to manually split them up in Photoshop but I would like to implement something in my program to do this for me. I'm using C++ in VS. So, basically I need to find a way for the PC to detect the near black strips in between the images on the film, isolate the images and save them as individual files.
Could someone give me some advice for this?
That sounds pretty simple compared to the things you've already implemented; you could
calculate an average pixel value per row, and call the resulting signal s(n) (n being the row number).
set a threshold for s(n), setting everything below that threshold to 0 and everything above to 1
Assuming you don't know the exact pixel height of the black bars and the negatives, search for periodicities in s(n). What I describe in the following is total overkill, but that's how I roll:
use FFTw to calculate a discrete fourier transform of s(n), call it S(f) (f being the frequency, i.e. 1/period).
find argmax(abs(S(f))); that f represents the distance between two black bars: number of rows / f is the bar distance.
S(f) is complex, and thus has an argument; arctan(imag(S(f_max))/real(S(f_max)))*number of rows will give you the position of the bars.
To calculate the width of the bars, you could do the same with the second highest peak of abs(S(f)), but it'll probably be easier to just count the average length of 0 around the calculated center positions of the black bars.
To get the exact width of the image strip, only take the pixels in which the image border may lie: r_left(x) would be the signal representing the few pixels in which the actual image might border to the filmstrip material, x being the coordinate along that row). Now, use a simplistic high pass filter (e.g. f(x):= r_left(x)-r_left(x-1)) to find the sharpest edge in that region (argmax(abs(f(x)))). Use the average of these edges as the border location.
By the way, if you want to write a source block that takes your scanned image as input and outputs a stream of pixel row vectors, using GNU Radio would offer you a nice method of having a flow graph of connected signal processing blocks that does exactly what you want, without you having to care about getting data from A to B.
I forgot to add: Use the resulting coordinates with something like openCV, or any other library capable of reading images and specifying sub-images by coordinates as well as saving to new images.

resample an image from pixel to millimiters

I have an image (logical values), like this
I need to get this image resampled from pixel to mm or cm; this is the code I use to get the resampling:
function [ Ires ] = imresample3( I, pixDim )
[r,c]=size(I);
x=1:1:c;
y=1:1:r;
[X,Y]=meshgrid(x,y);
rn=r*pixDim;
cn=c*pixDim;
xNew=1:pixDim:cn;
yNew=1:pixDim:rn;
[Xnew,Ynew]=meshgrid(xNew,yNew);
Id=double(I);
Ires=interp2(X,Y,Id,Xnew,Ynew);
end
What I get is a black image. I suspect that this code does something that is not what I have in mind: it seems to take only the upper-left part of the image.
What I want is, instead, to have the same image on a mm/cm scale: what I expect is that every white pixel should be mapped from the original position to the new position (in mm/cm); what happen is certainly not what I expect.
I'm not sure that interp2 is the right command to use.
I don't want to resize the image, I just want to go from pixel world to mm/cm world.
pixDim is of course the dimension of the image pixel, obtained dividing the height of the ear in cm by the height of the ear in mm (and it is on average 0.019 cm).
Any ideas?
EDIT: I was quite sure that the code had no sense, but someone told me to do that way...anyway, if I have two edged ears, I need first to scale both the the real dimension and then perform some operations on them. What I mean with "real dimension" is that if one has size 6.5x3.5cm and the other has size 6x3.2cm, I need to perform operations on this dimensions.
I don't get how can I move from the pixel dimension to cm dimension BEFORE doing operation.
I want to move from one world to the other because I want to get rid of the capturing distance (because I suppose that if a picture of the ear is taken near and the other is taken far, they should have different size in pixel dimension).
Am I correct? There is a way to do it? I thought I can plot the ear scaling the axis, but then I suppose I cannot subtract one from the other, right?
Matlab does not use units. To apply your factor of 0.019cm/pixel you have to scale by a factor of 0.019 to have a 1cm grid, but this would cause any artefact below a size of 1cm to be lost.
Best practice is to display the data using multiple axis, one for cm and one for pixels. It's explained here: http://www.mathworks.de/de/help/matlab/creating_plots/using-multiple-x-and-y-axes.html
Any function processing the data should be independent of the scale or use the scale factor as an input argument, everything else is a sign of some serious algorithmic issues.

Is there a algorithm of solarisation?

i'm searching a algorithm to produce a solarisation effect of a picture. Have someone a link or a algorithm? I#m interessted in other filters too, like sepia or cartoon. For sepia i found some code here. On the web i found not much infos about the implementation of those filters.
greetings
solarisation means that the response curve is not monotonic (instead of simply increasing in brightness, the "output" starts bright, gets dimmer, and then increases again, as the "input" gets brighter). the easiest way to implement it (for some value of easy) is as a special case of a more general process which transforms pixel values.
here's some python-ish pseudocode for the main routine:
def transform(image, f):
for pixel in image:
pixel = f(pixel)
if we choose pixels to be values between 0 and 1 (normalise whatever values you have, and if you have colours treat R, G and B the same) then you can modify gamma (change contrast) by using
transform(image, f(x): x^gamma)
for solarisation, you need a function that decreases then increases again. so something like 1-4x+4x^2:
transform(image, f(x): 1-4x+4x^2)
in case that's all a bit opaque, here are some numbers to make things clearer:
if the input image is 0 (black) then the output would be 1-4*0+4*0^2 = 1 (white)
if the input image is 0.5 (grey) then the output would be 1-4*0.5+4*0.5^2 = 1-2+1 = 0 (black)
if the input image is 1 (white) then the output would be 1-4*1+4*1^2 = 1 (white)
then you could take it further by adding some parameters to the curve (eg a + bx + cx^2) that the user can alter.
(actually, it can be more general - it can have multiple peaks or go black at bright points - there's an ansel adams image with a black sun, for example. the idea's the same, just use a higher order polynomial, or change the sign of the parameters above - a -ve c will make bright areas dark. and you can use splines rather than polynomials. basically, it's a mapping from input to output that goes "up and down" and within that there's a lot of flexibility...).

Resources