Search code examples
image-processingjulia

Linefitting how to deal with continuous values?


I'm trying to fit a line using quadratic poly, but because the fit results in continuous values, the integer conversion (for CartesianIndex) rounds it off, and I loose data at that pixel.

I tried the method here. So I get new y values as

using Images, Polynomials, Plots,ImageView

img = load("jTjYb.png")
img = Gray.(img)
img = img[end:-1:1, :]
nodes = findall(img.>0)

xdata = map(p->p[2], nodes)
ydata = map(p->p[1], nodes)
f = fit(xdata, ydata, 2)
ydata_new .= round.(Int, f.(xdata)
new_line_fitted_img=zeros(size(img))
new_line_fitted_img[xdata,ydata_new].=1
imshow(new_line_fitted_img)

which results in chopped line as below

enter image description here whereas I was expecting it to be continuous line as it was in pre-processing

enter image description here


Solution

  • Do you expect the following:

    Raw Image Fitted Polynomial Superposition
    enter image description here enter image description here enter image description here

    Code:

    using Images, Polynomials
    
    img = load("img.png");
    img = Gray.(img)
    
    fx(data, dCoef, cCoef, bCoef, aCoef) = @. data^3 *aCoef + data^2 *bCoef + data*cCoef + dCoef;
    
    function fit_poly(img::Array{<:Gray, 2})
      img = img[end:-1:1, :]
      nodes = findall(img.>0)
      xdata = map(p->p[2], nodes)
      ydata = map(p->p[1], nodes)
      f = fit(xdata, ydata, 3)
      xdt = unique(xdata)
      xdt, fx(xdt, f.coeffs...)
    end;
    
    
    function draw_poly!(X, y)
      the_min = minimum(y)
      if the_min<0
        y .-= the_min - 1
      end
      initialized_img = Gray.(zeros(maximum(X), maximum(y)))
      initialized_img[CartesianIndex.(X, y)] .= 1
      dif = diff(y)
      for i in eachindex(dif)
        the_dif = dif[i]
        if abs(the_dif) >= 2
          segment = the_dif ÷ 2
          initialized_img[i, y[i]:y[i]+segment] .= 1
          initialized_img[i+1, y[i]+segment+1:y[i+1]-1] .= 1
        end
      end
      rotl90(initialized_img)
    end;
    
    X, y = fit_poly(img);
    y = convert(Vector{Int64}, round.(y));
    draw_poly!(X, y)