-3

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?

Sardar Usama
  • 19,536
  • 9
  • 36
  • 58
  • I don't understand what you want. You want to discretize the sinusoidal curve and approach it with line segments? The delta_y will just be the difference between two consecutive points or if you want it analytically, it will be the derivative of your function (in your case a `cos` function) –  Dec 22 '16 at 09:20
  • how does that make any sense? – Piglet Dec 22 '16 at 18:06
  • Are you asking for the length of the sinusoidal curve. ie if it was a rope and you want to know (in a straight line) how much length of rope it takes to make that particular sinusoid? – Sneaky Polar Bear Dec 23 '16 at 18:41
  • Yes, the image I have is a binary image, with a sinosidal curve. I want to save these all curve values by pixel in array then want to draw them as a straight line in output image. The next task is I have to draw again the sinosidal curve from that straight line image with saved information from the first image. Moreover my task is, there is a sinusoidal pipe( definitely there are two sinoisides as sides of pipe and some bobs in it) I want to make them all in a straight line in output image.i will upload a sample images – altaf ur Rahman Dec 24 '16 at 19:25
  • Doing it in spatial coordinate system will be a better choice – altaf ur Rahman Dec 24 '16 at 19:26
  • I have uploaded the new image, and hope you could understand my problem – altaf ur Rahman Dec 24 '16 at 19:46
  • @Sneaky Polar Bear – altaf ur Rahman Dec 24 '16 at 19:51
  • Correction: In previous comments, the text is "The next task is I have to draw again the sinusoidal curve from that straight line image with no saved information from the first image" I mean this is another task – altaf ur Rahman Dec 24 '16 at 19:56
  • I posted an answer below... but I am still not quite sure I understand what you are asking. What I posted will vertically distort lines for you, but technically is ignorant to (arclength?) ie if you have several blobs near eachother in an upward hump of the sinusoid, if you were to "stretch out" that sinusoid, they would remain almost the same distance from eachother after stretching, but if you vertically warp (as I have explained below) they will actually get pushed towards eachother... – Sneaky Polar Bear Dec 25 '16 at 02:38

3 Answers3

0

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

rahnema1
  • 15,264
  • 3
  • 15
  • 27
  • 1
    what in gods name are you doing here? – Piglet Dec 22 '16 at 18:09
  • the blue curve is converted to straight line – rahnema1 Dec 22 '16 at 18:31
  • @Piglet Don't worry. I think this is all smoke and mirrors too. – rayryeng Dec 23 '16 at 06:26
  • Absolutely. What in Gods name are you doing here? A sine wave is an array of values vs.time. If you don't like those values make them zero. Or choose a value you DO like. – J. McCabe Dec 23 '16 at 18:40
  • @J.McCabe a possible application is that when we have multiple curves in a plot and we want to set one of them (for example blue curve) as reference and compare variation of other curves relative to it – rahnema1 Dec 23 '16 at 18:45
  • @rahnema1 your approach causes a lot of noise in the output. also I don't get why you don't just calculate amplitude and wavelength, knowing it's a sine wave... – Piglet Dec 23 '16 at 19:04
  • @Piglet I provided a general method that can be use with any curve. If you have a better solution you may send your answer. – rahnema1 Dec 23 '16 at 19:10
  • Which one thing is not clear, just the image is uploaded needs to be rotated to understand my problem. Only have a look at 1- input => output image. Just I have to make this sinusoidal pipe a straight pipe in output image. My another task is to make a sinusoidal pipe from straight pipe. Hope you people could understand. Straight pipe will be on horizontal axis, – altaf ur Rahman Dec 25 '16 at 03:49
  • Thanks @rahnema1, Actually my problem is little bit different. i have uploaded the new image [2]. ( it is shown rotated, but you can download to see it properly). Hope you could understand from the image what i want. Thanks once again – altaf ur Rahman Dec 25 '16 at 20:29
0

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.

Sneaky Polar Bear
  • 1,611
  • 2
  • 17
  • 29
  • Your logic seems soundful. but i think you are really not understanding my question. kindly have a look at 2nd image ( rotate first to see clearly).thanks – altaf ur Rahman Dec 27 '16 at 14:30
0

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.

Sneaky Polar Bear
  • 1,611
  • 2
  • 17
  • 29