рдПрдл #, рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо рдХреЛ рд╕рдВрд░реЗрдЦрд┐рдд рдХрд░рдХреЗ рдЫрд╡рд┐ рдХреЗ рд╡рд┐рдкрд░реАрдд рдХреЛ рдмрдврд╝рд╛рддрд╛ рд╣реИ

рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо рд╕рдВрд░реЗрдЦрдг рдСрдкрд░реЗрд╢рди (рдмрдврд╝рддреА рд╣реБрдИ рд╡рд┐рдкрд░реАрддрддрд╛) рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдХреНрд╕рд░ рдЫрд╡рд┐ рдХреА рдЧреБрдгрд╡рддреНрддрд╛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдХреЗ рдврд╛рдВрдЪреЗ рдореЗрдВ, рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ , рдЗрд╕рдХреЗ рд╕рдВрд░реЗрдЦрдг рдХреЗ рд▓рд┐рдП рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рд╕рд┐рджреНрдзрд╛рдВрдд рдФрд░ рдЗрд╕ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ ред рдЫрд╡рд┐ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо OpenCV рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ ред рд╕рд╛рде рд╣реА, рд╣рдо рдЕрдкрдиреЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдФрд░ рдЙрд╕ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рддреБрд▓рдирд╛рддреНрдордХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА OpenCV рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ ред



рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо рдПрдХ рдлрд╝рдВрдХреНрд╢рди h (x) рд╣реИ , рдЬреЛ рдХреБрд▓ рдкрд┐рдХреНрд╕реЗрд▓ рдХреА рд╕рдВрдЦреНрдпрд╛ рджреЗрддрд╛ рд╣реИ рдЬрд┐рдирдХреА рдЪрдордХ x рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ ред


рд╣рдлрд╝реНрдлрд╝реЛрдЧреНрд░рд╛рдо рдПрдЪ рдСрдлрд╝ рд╣рдлрд╝реНрдлрд╝рдЯреЛрди рдЗрдореЗрдЬ I рджреНрд╡рд╛рд░рд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ

h(m)=|(r,c)|I(r,c)=m|


, рдЬрд╣рд╛рдВ рдореАрдЯрд░ рдЪрдордХ рдореВрд▓реНрдпреЛрдВ рдХреЗ рдЕрдВрддрд░рд╛рд▓ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИ

рдиреАрдЪреЗ рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдЫрджреНрдо рдХреЛрдб рд╣реИред


//   H    I.

procedure histogram(I,H);
{
    //     .
    for i := 0 to MaxVal
        H[i] := 0;

    //   .
    for L := 0 to MaxRow
        for P := 0 to MaxCol {
            grayval := I[r,c];
            H[grayval] := H[grayval] + 1;
        };
}

рдиреЗрддреНрд░рд╣реАрди, рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо рдПрдХ рдЖрдпрдд рд╣реИ, рдЬрд┐рд╕рдХреА рдЪреМрдбрд╝рд╛рдИ рдореВрд▓ рдЫрд╡рд┐ рдореЗрдВ рдПрдХ рдмрд┐рдВрджреБ рдХреА рдЪрдордХ рдХреЗ рдЕрдзрд┐рдХрддрдо рд╕рдВрднрд╡ рдореВрд▓реНрдп рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред рд╕реНрдХреЗрд▓ рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо 0 рд╕реЗ 255 рддрдХ рдЕрдВрдХреЛрдВ рдХреА рдЪрдордХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо рдХреА рдЪреМрдбрд╝рд╛рдИ 256 рд╣реЛрдЧреАред рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо рдХреА рдКрдВрдЪрд╛рдИ рдХреЛрдИ рднреА рд╣реЛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЖрдпрддрд╛рдХрд╛рд░ рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдореНрд╕ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред


, тАФ 256 ( ), . .


1. h(x)



. тАФ cdf(x) .


, OpenCV , , . , , . F# OpenCVSharp4.


, Visual Studio, . , MacOS, , "runtimes/osx-x64/native/libOpenCvSharpExtern.dylib" , .
Unable to load shared library 'OpenCvSharpExtern' or one of its dependencies


,


open OpenCvSharp
open Microsoft.FSharp.NativeInterop

// mat -   Mat  OpenCV
let getHistogram (mat: Mat) =
    //   
    let hx = Array.zeroCreate<int> 256
    //  
    mat.ForEachAsByte(fun value _ ->
                           let v = int (NativePtr.get value 0)
                           hx.[v] <- hx.[v] + 1)
    //  
    hx

, . X


cdx(x)=h(0)+h(1)+...+h(x)


, X. 1 ( ).


, cdf(x)


let getCdx hx = // hx - 
   //   
   hx |> Array.mapi (fun x _ -> if x > 0 then hx.[0..(x-1)] |> Array.sum else 0)


1 , . ( ), . , , .


2.


2.



, .


:


f(x)=round(cdf(x)тИТcdfminpixelsтИТ1тЛЕ255)



cdf(x) тАФ X
cdf_min тАФ ,
pixels тАФ
255 тАФ . 255
round тАФ


F# :


//  cdf_min
let cdxMin = cdx |> Array.filter (fun v -> v > 0) |> Array.min
//      
let totalPixels = src.Rows * src.Cols // src -   Mat   

for y in 0..src.Rows do
    for x in 0..src.Cols do
        //     
        let s = int(src.At<byte>(y, x))
        //     
        let fx = (float(cdx.[s]) - float(cdxMin))/(float(totalPixels - 1))*255.
        //    
        equalizeImage.Circle(x, y, 1, new Scalar(double(fx)))

, . . , OpenCV .


// Learn more about F# at http://fsharp.org
open OpenCvSharp
open Microsoft.FSharp.NativeInterop

//     
let getHistogram (mat: Mat) =
    let hx = Array.zeroCreate<int> 256
    mat.ForEachAsByte(fun value _ ->
                           let v = int (NativePtr.get value 0)
                           hx.[v] <- hx.[v] + 1)
    hx

//      
let getCdx hx =
    hx |> Array.mapi (fun x _ -> if x > 0 then hx.[0..(x-1)] |> Array.sum else 0)

//     
let drawHistogramAndCdx hx cdx (mat: Mat) =
    let histoWidth = 256
    let histoHeight = 256

    //     
    let cdxMax = cdx |> Array.max
    //      ( )
    //    
    let cdxK = float(histoHeight)/float(cdxMax)

    let histMax = hx |> Array.max
    let histK = float(histoHeight)/float(histMax)

    let histMat = new Mat(histoWidth, histoHeight, MatType.CV_8UC4)
    hx
    |> Array.iteri (fun x v ->
                        let histDy = int(float(v)*histK)
                        let cdxDy = int(float(cdx.[x])*cdxK)
                        //   h(x)
                        mat.Line(x, histoHeight-1, x, histoHeight-1-histDy, Scalar.White)
                        //    cdx(x)
                        mat.Circle(x, histoHeight-cdxDy, 1, Scalar.Blue))

[<EntryPoint>]
let main argv =

    let histoWidth = 256
    let histoHeight = 256

    let src = Cv2.ImRead("cat.jpg", ImreadModes.Grayscale)
    let equalizeImage = new Mat(src.Rows, src.Cols, MatType.CV_8UC1)

    // calculate histogram h(x)
    let hx = getHistogram src

    // calculate cdf(x) = h(0) + h(1) + .. + h(x)
    let cdx = getCdx hx

    // draw histogram
    let histMat = new Mat(histoWidth, histoHeight, MatType.CV_8UC4)
    drawHistogramAndCdx hx cdx histMat

    // equalize the histogram
    let cdxMin = cdx |> Array.filter (fun v -> v > 0) |> Array.min
    let totalPixels = src.Rows * src.Cols

    for y in 0..src.Rows do
        for x in 0..src.Cols do
            let s = int(src.At<byte>(y, x))
            let fx = (float(cdx.[s]) - float(cdxMin))/(float(totalPixels - 1))*255.
            //equalizeImage.Set<Scalar>(y, x, new Scalar(double(fx)))
            equalizeImage.Circle(x, y, 1, new Scalar(double(fx)))

    // calculate equalize histogram
    let hx2 = getHistogram equalizeImage
    let cdx2 = getCdx hx2

    let histMat2 = new Mat(histoWidth, histoHeight, MatType.CV_8UC4)
    drawHistogramAndCdx hx2 cdx2 histMat2

    // opencv equalize histogram
    let opencCVImage = new Mat(src.Rows, src.Cols, MatType.CV_8UC1)
    let in1 = InputArray.Create(src)
    let in2 = OutputArray.Create(opencCVImage)

    Cv2.EqualizeHist(in1, in2)

    // get opencv histogram
    let hx3 = getHistogram opencCVImage
    let cdx3 = getCdx hx3

    let histMat3 = new Mat(histoWidth, histoHeight, MatType.CV_8UC4)
    drawHistogramAndCdx hx3 cdx2 histMat3

    // show results
    use w1 = new Window("original image", src)
    use w2 = new Window("original histogram", histMat)

    use w3 = new Window("custom equalize image", equalizeImage)
    use w4 = new Window("custom equalize histogram", histMat2)

    use w5 = new Window("opencv equalize image", opencCVImage)
    use w6 = new Window("opencv equalize histogram", histMat3)

    Cv2.WaitKey() |> ignore

    0 // return an integer exit code


3.


, , OpenCV.


( ), тАФ , тАФ OpenCV.







рд▓реЗрдЦ рдХрд╛ рд▓реЗрдЦрдХ рдореВрд▓ рд╕реЗ рдмрд╣реБрдд рджреВрд░ рд╣реИ рдФрд░ рдЙрд╕рдиреЗ рдХреБрдЫ рднреА рдирдпрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рдЬрдирддрд╛ рдХреЗ рд╕рд╛рдордиреЗ рдПрдХ рдФрд░ рдХрд╣рд╛рдиреА рдкреЗрд╢ рдХреА рд╣реИ рдХрд┐ рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо рд╕рдВрд░реЗрдЦрдг рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИред рд▓реЗрдЦ рдХрд╛ рдореБрдЦреНрдп рдЙрджреНрджреЗрд╢реНрдп рдХреЗрд╡рд▓ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдирд╣реАрдВ рдерд╛, рдмрд▓реНрдХрд┐ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЙрджрд╛рд╣рд░рдг рдФрд░ рд╕реНрд░реЛрдд рдХреЛрдб рджреЗрдирд╛ рдерд╛ рдЬрд┐рд╕реЗ рдЖрдк рдЦреБрдж рдХреЛ рдХреЙрдкреА рдФрд░ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд╕рдВрднрд╡рддрдГ рдкреНрд░рдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдмреЗрд╢рдХ, рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗрд╡рд▓ рдПрдХ рд╣реА рдирд╣реАрдВ рд╣реИ рдЬреЛ рдЫрд╡рд┐рдпреЛрдВ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдиреНрдп рдореБрджреНрджреЛрдВ рдХрд╛ рд╡рд┐рд╖рдп рд╣реИред


All Articles