将图像中的正弦曲线制成输出图像中的直线

时间:2016-12-22 06:59:00

标签: matlab image-processing computer-vision feature-detection

我必须在图像中制作一条正弦曲线,以在结果图像中输出相等的直线。

输入正弦图像的示例:
example of input sinusoidal image is here

我认为一个解决方案应该是:
在曲线的开始处放下x和y坐标的原点,这样我们就会在起点处有y=0。然后,上限点数将计为y= y-(delta_y),下限为y=y+(delta_y)

因此,为了使上点成为一条直线,我们得到的图像将是:

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

但如何计算水平x轴上每个deltaY的{​​{1}}(它显示曲线点与水平轴的距离)

另一个解决方案可能是,将曲线的所有信息保存在变量中并将其绘制为直线,但该怎么做?

3 个答案:

答案 0 :(得分:0)

由于曲线为蓝色,我们可以使用蓝色和红色通道中的信息来提取曲线。只需从蓝色通道中减去红色通道就会突出显示曲线:

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

enter image description here

在图像的每一列中,曲线的位置是行的索引,它的值是该列的最大值

    [~,im]=max(D);

所以我们可以使用行位置来移动每列,以便创建一条水平线。移动每列可能会增加图像的大小,因此需要通过将图像从顶部和底部填充原始图像的大小来增加图像的大小,以使填充图像的行大小为原始图像的3倍,并且填充值为255或白色

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

最后,每个频道cirshift每列的值为im

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

因此将使用以下代码创建结果:

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

答案 1 :(得分:0)

如果您确定初始图像中有正弦波,而不是计算零碎偏移量,您可以估算正弦方程:

幅度=(yMax - yMin)/ 2

offset =(yMax + yMin)/ 2

(xValley在xPeak之后立即需要成为山谷,或者你可以做到峰值到峰值,但它会改变方程,所以这是更紧凑的版本(即你需要看到更少的正弦曲线))

frequencyScale =π/(xValley - xPeak)

frequencyShift = xFirstZeroCrossRising

如果你能够计算所有这些,那就是你的等式:

y =偏移+幅度* sin(frequencyScale *(x + frequencyShift))

这个等式应该是您需要存储的一个图像,以便能够移动任何其他图像,它还可以用于生成偏移,以准确地取消图像中的正弦曲线。

所有这些术语都应该能够从图像中估算出来,而且难度相对较小。如果您无法弄清楚如何从图像中获取任何术语,请告诉我,我将特别解释这一术语。

答案 2 :(得分:0)

如果您正在寻找某种类型的距离图:

将第一个点放在曲线上并将其复制到输出图像中,然后测量该点与(曲线)线上的下一个点之间的距离。使用该距离仅沿x轴偏移(从第一个点)下一个点到输出图像。您可能希望逐个像素地执行此操作,或通过平均或跳跃来抓取像素块(逐像素将为您提供一些奇怪的数字噪声)

如果你想要更清洁,你需要设置一个足够小的步长,大致匹配最大正弦曲率而没有太多误差。然后,如上所述估计距离以设置边界,然后将起点和终点之间的每个像素插入到基于近似位置平均成为区间的图像中。 IE如果原始图像中的像素落在输出图像中的两个区间之间,则会将其拆分并将其加权部分添加到这两个区域。