Making a sinusoidal curve in an image into a straight line in the output image

816 views Asked by At

I have to make a sinusoidal curve in an image to output an equal straight line in the resulting image.

An example of input sinusoidal image:
example of input sinusoidal image is here

What I think is one solution should be:
Placing down the origin of x and y coordinates at the start of the curve, so we will have y=0 at the starting point. Then points on the upper limit will be counted as such that y= y-(delta_y) and for lower limits, y=y+(delta_y)

So to make upper points a straight line, our resulting image will be:

O[x,y-delta_y]= I[x,y];

But how to calculate deltaY for each y on horizontal x axis (it is showing the distance of curve points from horizontal axis)

Another solution could be, to save all information of the curve in a variable and to plot it as a straight line, but how to do it?

3

There are 3 answers

9
rahnema1 On

Since the curve is blue we can use information from the blue and red channels to extract the curve. Simply subtraction of red channel from blue channel will highlight the curve:

a= imread('kCiTx.jpg');
D=a(:,:,3)-a(:,:,1);

enter image description here

In each column of the image position of the curve is index of the row that it's value is the maximum of that column

    [~,im]=max(D);

so we can use row position to shift each column so to create a horizontal line. shifting each column potentially increases size of the image so it is required to increase size of the image by padding the image from top and bottom by the size of the original image so the padded image have the row size of 3 times of the original image and padding value is 255 or white color

pd = padarray(a,[size(a,1) 0 0], 255);

finally for each channel cirshift each column with value of im

for ch = 1:3
    for col = 1: size(a,2)
        pd(:,col,ch) = circshift(pd(:,col,ch),-im(col));
    end
end

So the result will be created with this code:

a= imread('kCiTx.jpg');
D=a(:,:,3)-a(:,:,1);
%position of curve found
[~,im]=max(D);
%pad image
pd = padarray(a,[size(a,1) 0 0], 255);
%shift columns to create a flat curve
for ch = 1:3
    for col = 1: size(a,2)
        pd(:,col,ch) = circshift(pd(:,col,ch),-im(col));
    end
end
figure,imshow(pd,[])

enter image description here

0
Sneaky Polar Bear On

If you are looking for some type of distance plot:

Take your first point on the curvy line and copy it into your output image, then measure the distance between that point and the next point on the (curvy) line. Use that distance to offset (from the first point) that next point into the output image only along the x axis. You may want to do it pixel by pixel, or grab clumps of pixels through averaging or jumping (as pixel by pixel will give you some weird digital noise)

If you want to be cleaner, you will want to set up a step size which was sufficiently small to approximately match the maximum sinusoidal curvature without too much error. Then, estimate the distance as stated above to set up bounds and then interpolate each pixel between the start and end point into the image averaging into bins based on approximate position. IE if a pixel from the original image would fall between two bins in the output image, you would split it and add its weighted parts to those two bins.

1
Sneaky Polar Bear On

If you are sure you have a sinusoid in your initial image, rather than calculating piece-meal offsets, you may as well estimate the sinusoidal equation:

amplitude = (yMax - yMin)/2

offset = (yMax + yMin)/2

(xValley needs to be the valley immediately after xPeak, alternately you could do peak to peak, but it changes the equation, so this is the more compact version (ie you need to see less of the sinusoid))

frequencyScale = π / (xValley - xPeak)

frequencyShift = xFirstZeroCrossRising

If you are able to calculate all of those, this is then your equation:

y = offset + amplitude * sin(frequencyScale * (x + frequencyShift))

This equation should be all you need to store from one image to be able to shift any other image, it can also be used to generate your offsets to exactly cancel your sinusoid in your image.

All of these terms should be able to be estimated from the image with relatively little difficulty. If you can not figure out how to get any of the terms from the image, let me know and I will explain that one in particular.