/// The thresholds are automatically defined with otsu on gradient magnitudes.
/// </summary>
/// <param name="img"></param>
-let findEdges (img: Image<Gray, float32>) : Matrix<byte> * Image<Gray, float32> * Image<Gray, float32> =
+let findEdges (img: Image<Gray, float32>) : Matrix<byte> * Matrix<float32> * Matrix<float32> =
let w = img.Width
let h = img.Height
use sobelKernel =
- new ConvolutionKernelF(array2D [[ 1.0f; 0.0f; -1.0f ]
- [ 2.0f; 0.0f; -2.0f ]
- [ 1.0f; 0.0f; -1.0f ]], Point(1, 1))
+ new Matrix<float32>(array2D [[ 1.0f; 0.0f; -1.0f ]
+ [ 2.0f; 0.0f; -2.0f ]
+ [ 1.0f; 0.0f; -1.0f ]])
- let xGradient = img.Convolution(sobelKernel)
- let yGradient = img.Convolution(sobelKernel.Transpose())
-
- let xGradientData = xGradient.Data
- let yGradientData = yGradient.Data
- for r in 0 .. h - 1 do
- xGradientData.[r, 0, 0] <- 0.f
- xGradientData.[r, w - 1, 0] <- 0.f
- yGradientData.[r, 0, 0] <- 0.f
- yGradientData.[r, w - 1, 0] <- 0.f
-
- for c in 0 .. w - 1 do
- xGradientData.[0, c, 0] <- 0.f
- xGradientData.[h - 1, c, 0] <- 0.f
- yGradientData.[0, c, 0] <- 0.f
- yGradientData.[h - 1, c, 0] <- 0.f
+ let xGradient = new Matrix<float32>(img.Size)
+ let yGradient = new Matrix<float32>(img.Size)
+ CvInvoke.Filter2D(img, xGradient, sobelKernel, Point(1, 1))
+ CvInvoke.Filter2D(img, yGradient, sobelKernel.Transpose(), Point(1, 1))
use magnitudes = new Matrix<float32>(xGradient.Size)
use angles = new Matrix<float32>(xGradient.Size)
for i in 1 .. h - 2 do
for j in 1 .. w - 2 do
- let vx = xGradientData.[i, j, 0]
- let vy = yGradientData.[i, j, 0]
+ let vx = xGradientData.[i, j]
+ let vy = yGradientData.[i, j]
if vx <> 0.f || vy <> 0.f
then
let angle = anglesData.[i, j]
let drawEllipse (img: Image<'TColor, 'TDepth>) (e: Ellipse) (color: 'TColor) (alpha: float) =
if alpha >= 1.0
then
- img.Draw(Emgu.CV.Structure.Ellipse(PointF(float32 e.Cx, float32 e.Cy), SizeF(2.f * e.B, 2.f * e.A), e.Alpha / PI * 180.f), color, 1, CvEnum.LineType.AntiAlias)
+ img.Draw(Emgu.CV.Structure.Ellipse(PointF(e.Cx, e.Cy), SizeF(2.f * e.B, 2.f * e.A), e.Alpha / PI * 180.f), color, 1, CvEnum.LineType.AntiAlias)
else
let windowPosX = e.Cx - e.A - 5.f
let gapX = windowPosX - (float32 (int windowPosX))
if roi = img.ROI // We do not display ellipses touching the edges (FIXME)
then
use i = new Image<'TColor, 'TDepth>(img.ROI.Size)
- i.Draw(Emgu.CV.Structure.Ellipse(PointF(float32 <| (e.A + 5.f + gapX) , float32 <| (e.A + 5.f + gapY)), SizeF(2.f * e.B, 2.f * e.A), e.Alpha / PI * 180.f), color, 1, CvEnum.LineType.AntiAlias)
+ i.Draw(Emgu.CV.Structure.Ellipse(PointF(e.A + 5.f + gapX, e.A + 5.f + gapY), SizeF(2.f * e.B, 2.f * e.A), e.Alpha / PI * 180.f), color, 1, CvEnum.LineType.AntiAlias)
CvInvoke.AddWeighted(img, 1.0, i, alpha, 0.0, img)
img.ROI <- Rectangle.Empty