public void createEqualizedHistogram()
        {
            float[]   range  = { 0, 255 };
            float[][] ranges = { range };

            int histogramSize = 255;

            float minimumValue, maximumValue = 0;

            histogramImage = Cv.CreateImage(srcImage.Size, BitDepth.U8, 1);
            convertionGrayScale();

            Cv.EqualizeHist(grayscaleImage, grayscaleImage);

            CvHistogram histogramR = Cv.CreateHist(new int[] { histogramSize }, HistogramFormat.Array, ranges, true);

            Cv.CalcHist(grayscaleImage, histogramR);
            Cv.GetMinMaxHistValue(histogramR, out minimumValue, out maximumValue);
            Cv.Scale(histogramR.Bins, histogramR.Bins, ((double)histogramImage.Height) / maximumValue, 0);
            histogramImage.Set(CvColor.White);
            int bin_red = Cv.Round((double)histogramImage.Width / histogramSize);

            int r;

            for (r = 0; r < histogramSize; r++)
            {
                histogramImage.Rectangle(new CvPoint(r * bin_red, grayscaleImage.Height), new CvPoint((r + 1) * bin_red, grayscaleImage.Height - Cv.Round(histogramR.Bins[r])), CvColor.Black, -1, LineType.Link8, 0);
            }

            Cv.SaveImage("newHistoMode1.jpg", histogramImage);
            Cv.SaveImage("newHistoMode2.jpg", grayscaleImage);
        }
Exemple #2
0
        /// <summary>
        /// ヒストグラムの計算
        /// </summary>
        /// <param name="img"></param>
        /// <param name="hist"></param>
        private static void CalcHist(IplImage img, CvHistogram hist)
        {
            hist.Calc(img);
            float minValue, maxValue;

            hist.GetMinMaxValue(out minValue, out maxValue);
            Cv.Scale(hist.Bins, hist.Bins, ((double)img.Height) / maxValue, 0);
        }
Exemple #3
0
        public void DrawHistogram()
        {
            //variable declaration
            float []  range = { 0, 255 };
            float[][] ranges = { range }; //defining 2D array
            int       his_size = 256;
            float     min_value, max_value = 0;

            //call convertgray function
            ConvertToGray();

            //create an inage to hold the histogarm
            histImage = Cv.CreateImage(image1.Size, BitDepth.U8, 1);

            //create a histogarm to store information from the image
            CvHistogram hist = Cv.CreateHist(new int [] { his_size },
                                             HistogramFormat.Array, ranges, true);

            //rangers ==> starting and ending values of the range
            //HistogramFormat.Array ==> 2D array
            //true ==> each scale of the histogarm is eqaully distributed
            //new int [] { his_size } ==> y axis is given as a dynamic array since the limit is not known/fixed

            //calculate the histogram and apply to histogram
            Cv.CalcHist(image1, hist);

            //grab min and max
            Cv.GetMinMaxHistValue(hist, out min_value, out max_value);

            //scale the bin values (gaps) so that thay will fit in the image representation
            Cv.Scale(hist.Bins, hist.Bins, ((double)histImage.Height) / max_value, 0);

            //hist.Bins ==> for the source and the destination to be scaled.
            //((double) histImage.Height) / max_value ==> scale value.
            //0 ==> to represent a null mask. its a default parameter.

            //set all histogram values to 255
            histImage.Set(CvColor.White);

            //create a factor for scaling along the width
            int bin_w = Cv.Round(((double)histImage.Width / his_size));

            int i;

            for (i = 0; i < his_size; i++)
            {
                histImage.Rectangle(
                    new CvPoint(i * bin_w, image1.Height),
                    new CvPoint((i + 1) * bin_w, image1.Height - Cv.Round(hist.Bins[i])),
                    CvColor.Black,  //line drawn in black
                    -1,             //thickness
                    LineType.Link8, //indicated the link type (connected)
                    0               //shift bit (factional bits in the coordinate)
                    );
            }
            Cv.SaveImage("3.jpg", histImage);
        }
Exemple #4
0
        // OpenCVSharp was so inconsequential with its own copy function that I had to wrap it up and make it into something sensible
        static public CvHistogram CopyHistogram(CvHistogram source)
        {
            int[] sizes = new int[source.Dim];
            for (int i = 0; i < source.Bins.Dims; ++i)
            {
                sizes[i] = source.Bins.GetDimSize(i);
            }
            CvHistogram newHisto = new CvHistogram(sizes, source.Type);

            source.Copy(newHisto);               // NOTE : source is copied INTO newHisto = "CopyTo"
            return(newHisto);
        }
Exemple #5
0
        public Histogram()
        {
            // cvCalcHist
            // コントラストや明度をいろいろ変えられるサンプル

            const int histSize = 64;

            float[]   range0 = { 0, 256 };
            float[][] ranges = { range0 };

            // 画像の読み込み
            using (IplImage srcImg = new IplImage(Const.ImageLenna, LoadMode.GrayScale))
                using (IplImage dstImg = srcImg.Clone())
                    using (IplImage histImg = new IplImage(new CvSize(400, 400), BitDepth.U8, 1))
                        using (CvHistogram hist = new CvHistogram(new int[] { histSize }, HistogramFormat.Array, ranges, true))
                        {
                            using (CvWindow windowImage = new CvWindow("image", WindowMode.AutoSize))
                                using (CvWindow windowHist = new CvWindow("histogram", WindowMode.AutoSize))
                                {
                                    // トラックバーが動かされた時の処理
                                    CvTrackbar         ctBrightness = null;
                                    CvTrackbar         ctContrast   = null;
                                    CvTrackbarCallback callback     = delegate(int pos)
                                    {
                                        int brightness = ctBrightness.Pos - 100;
                                        int contrast   = ctContrast.Pos - 100;
                                        // LUTの適用
                                        byte[] lut = CalcLut(contrast, brightness);
                                        srcImg.LUT(dstImg, lut);
                                        // ヒストグラムの描画
                                        CalcHist(dstImg, hist);
                                        DrawHist(histImg, hist, histSize);
                                        // ウィンドウに表示
                                        windowImage.ShowImage(dstImg);
                                        windowHist.ShowImage(histImg);
                                        dstImg.Zero();
                                        histImg.Zero();
                                    };

                                    // トラックバーの作成
                                    // (OpenCVでは現在位置にポインタを渡すことでトラックバーの位置の変化が取得できるが、
                                    // .NETではGCによりポインタが移動してしまうので廃止した。別の方法でうまく取得すべし。)
                                    ctBrightness = windowImage.CreateTrackbar("brightness", 100, 200, callback);
                                    ctContrast   = windowImage.CreateTrackbar("contrast", 100, 200, callback);
                                    // 初回描画
                                    callback(0);

                                    // キー入力待ち
                                    Cv.WaitKey(0);
                                }
                        }
        }
Exemple #6
0
        /// <summary>
        /// ヒストグラムの描画
        /// </summary>
        /// <param name="img"></param>
        /// <param name="hist"></param>
        /// <param name="histSize"></param>
        private static void DrawHist(IplImage img, CvHistogram hist, int histSize)
        {
            img.Set(CvColor.White);
            int binW = Cv.Round((double)img.Width / histSize);

            for (int i = 0; i < histSize; i++)
            {
                img.Rectangle(
                    new CvPoint(i * binW, img.Height),
                    new CvPoint((i + 1) * binW, img.Height - Cv.Round(hist.Bins[i])),
                    CvColor.Black, -1, LineType.AntiAlias, 0
                    );
            }
        }
Exemple #7
0
        public IplImage BuildHist(IplImage src_tmp)
        {
            const int histSize = 64;

            float[]   range0 = { 0, 256 };
            float[][] ranges = { range0 };
            // 화상의 읽기
            using (IplImage srcImg = new IplImage(src_tmp.Size, BitDepth.U8, 1))
                using (IplImage dstImg = new IplImage(src_tmp.Size, BitDepth.U8, 1))
                    using (IplImage histImg = new IplImage(new CvSize(400, 400), BitDepth.U8, 1))
                        using (CvHistogram hist = new CvHistogram(new int[] { histSize }, HistogramFormat.Array, ranges, true))
                        {
                            src_tmp.CvtColor(srcImg, ColorConversion.BgrToGray);
                            srcImg.Copy(dstImg);
                            using (CvWindow windowImage = new CvWindow("변환된 이미지", WindowMode.AutoSize))
                                using (CvWindow windowHist = new CvWindow("히스토그램", WindowMode.AutoSize))
                                {
                                    // 트랙바가 동작되었을 때의 처리
                                    CvTrackbar         ctBrightness = null;
                                    CvTrackbar         ctContrast   = null;
                                    CvTrackbarCallback callback     = delegate(int pos)
                                    {
                                        int brightness = ctBrightness.Pos - 100;
                                        int contrast   = ctContrast.Pos - 100;
                                        // LUT의 적용
                                        byte[] lut = CalcLut(contrast, brightness);
                                        srcImg.LUT(dstImg, lut);
                                        // 히스토그램 그리기
                                        CalcHist(dstImg, hist);
                                        DrawHist(histImg, hist, histSize);
                                        // 윈도우에 표시
                                        DstHist = histImg.Clone();
                                        windowImage.ShowImage(dstImg);
                                        windowHist.ShowImage(histImg);
                                        dstImg.Zero();
                                        histImg.Zero();
                                    };
                                    // 트랙바의 작성
                                    ctBrightness = windowImage.CreateTrackbar("명도", 100, 200, callback);
                                    ctContrast   = windowImage.CreateTrackbar("대조", 100, 200, callback);
                                    // 첫회 그리기
                                    callback(0);
                                    // 키 입력대기
                                    Cv.WaitKey(0);
                                }
                            return(DstHist);
                        }
        }
Exemple #8
0
        /// <summary>
        /// バックプロジェクションにより肌色領域を求める
        /// </summary>
        /// <param name="imgSrc"></param>
        /// <param name="hsvPlanes"></param>
        /// <param name="imgRender"></param>
        private void RetrieveFleshRegion(IplImage imgSrc, IplImage[] hsvPlanes, IplImage imgDst)
        {
            int[] histSize = new int[] {30, 32};
            float[] hRanges = {0.0f, 20f};
            float[] sRanges = {50f, 255f};
            float[][] ranges = {hRanges, sRanges};

            imgDst.Zero();
            using (CvHistogram hist = new CvHistogram(histSize, HistogramFormat.Array, ranges, true))
            {
                hist.Calc(hsvPlanes, false, null);
                float minValue, maxValue;
                hist.GetMinMaxValue(out minValue, out maxValue);
                hist.Normalize(imgSrc.Width * imgSrc.Height * 255 / maxValue);
                hist.CalcBackProject(hsvPlanes, imgDst);
            }
        }
Exemple #9
0
        /// <summary>
        /// Gets flesh regions by histogram back projection
        /// </summary>
        /// <param name="imgSrc"></param>
        /// <param name="hsvPlanes"></param>
        /// <param name="imgRender"></param>
        private void RetrieveFleshRegion(IplImage imgSrc, IplImage[] hsvPlanes, IplImage imgDst)
        {
            int[]     histSize = new int[] { 30, 32 };
            float[]   hRanges  = { 0.0f, 20f };
            float[]   sRanges  = { 50f, 255f };
            float[][] ranges   = { hRanges, sRanges };

            imgDst.Zero();
            using (CvHistogram hist = new CvHistogram(histSize, HistogramFormat.Array, ranges, true))
            {
                hist.Calc(hsvPlanes, false, null);
                float minValue, maxValue;
                hist.GetMinMaxValue(out minValue, out maxValue);
                hist.Normalize(imgSrc.Width * imgSrc.Height * 255 / maxValue);
                hist.CalcBackProject(hsvPlanes, imgDst);
            }
        }
Exemple #10
0
        public Histogram()
        {
            // cvCalcHist

            const int histSize = 64;

            float[]   range0 = { 0, 256 };
            float[][] ranges = { range0 };

            using (IplImage srcImg = new IplImage(FilePath.Image.Lenna, LoadMode.GrayScale))
                using (IplImage dstImg = srcImg.Clone())
                    using (IplImage histImg = new IplImage(new CvSize(400, 400), BitDepth.U8, 1))
                        using (CvHistogram hist = new CvHistogram(new int[] { histSize }, HistogramFormat.Array, ranges, true))
                        {
                            using (CvWindow windowImage = new CvWindow("image", WindowMode.AutoSize))
                                using (CvWindow windowHist = new CvWindow("histogram", WindowMode.AutoSize))
                                {
                                    CvTrackbar         ctBrightness = null;
                                    CvTrackbar         ctContrast   = null;
                                    CvTrackbarCallback callback     = delegate(int pos)
                                    {
                                        int brightness = ctBrightness.Pos - 100;
                                        int contrast   = ctContrast.Pos - 100;
                                        // perform LUT
                                        byte[] lut = CalcLut(contrast, brightness);
                                        srcImg.LUT(dstImg, lut);
                                        // draws histogram
                                        CalcHist(dstImg, hist);
                                        DrawHist(histImg, hist, histSize);

                                        windowImage.ShowImage(dstImg);
                                        windowHist.ShowImage(histImg);
                                        dstImg.Zero();
                                        histImg.Zero();
                                    };

                                    ctBrightness = windowImage.CreateTrackbar("brightness", 100, 200, callback);
                                    ctContrast   = windowImage.CreateTrackbar("contrast", 100, 200, callback);
                                    // initial action
                                    callback(0);

                                    Cv.WaitKey(0);
                                }
                        }
        }
Exemple #11
0
        void TransformImage()
        {
            if (maskImage.ptr == IntPtr.Zero)
            {
                maskImage = cvlib.CvCreateImage(new CvSize(firstFrame.width, firstFrame.height), (int)cvlib.IPL_DEPTH_8U, 1);
                cvlib.CvSet(ref maskImage, new CvScalar(1, 1, 1, 1));
            }
            // remove background
            //cvlib.CvSub(ref firstFrame, ref currentFrame, ref currentFrame, ref maskImage);

            // normalize
            CvHistogram hist = cvlib.CvCreateHist(1, new[] { 256 }, cvlib.CV_HIST_ARRAY, IntPtr.Zero, 1);

            cvlib.CvCalcHist(new[] { currentFrame.ptr }, ref hist, 0);
            cvlib.CvNormalizeHist(ref hist, 20000);
            cvlib.CvCalcBackProject(ref currentFrame, ref currentFrame, ref hist);
            cvlib.CvReleaseHist(ref hist);
        }
        ////// PART B///////

        public void drawHistogram5a()
        {
            srcImage2 = Cv.LoadImage("5a.png", LoadMode.Color);

            float[]   range = { 0, 255 };
            float[][] ranges = { range };
            int       hist_size = 255;
            float     min_value, max_value = 0;

            //Convert colour image into gray
            IplImage gray = Cv.CreateImage(srcImage2.Size, BitDepth.U8, 1);

            Cv.CvtColor(srcImage2, gray, ColorConversion.RgbToGray);

            //Create an image to hold the histogram
            IplImage histImage = Cv.CreateImage(srcImage2.Size, BitDepth.U8, 1);

            //Create a histogram to store the information from image
            CvHistogram hist = Cv.CreateHist(new int[] { hist_size }, HistogramFormat.Array, ranges, true);

            //Calculate the histogram and apply to hist
            Cv.CalcHist(gray, hist);

            //Grab the minimum & maximum values from the image
            Cv.GetMinMaxHistValue(hist, out min_value, out max_value);

            //Scale the bin values to fit to image representation
            Cv.Scale(hist.Bins, hist.Bins, ((double)histImage.Height) / max_value, 0);

            //Set background color to white
            histImage.Set(CvColor.White);

            int bin_w = Cv.Round((double)histImage.Width / hist_size);

            //Draw Values on Image - Here we will iterate across the histogram bins and apply the values to the image.
            for (int i = 0; i < hist_size; i++)
            {
                histImage.Rectangle(new CvPoint(i * bin_w, gray.Height), new CvPoint((i + 1) * bin_w, gray.Height - Cv.Round(hist.Bins[i])), CvColor.Black, 1, LineType.Link8, 0);
            }

            Cv.SaveImage("5ahistogram.png", histImage);
        }
    // Creates an image from a 2D Histogram (x axis = Hue, y axis = Saturation)
    void DrawHSHistogram(CvHistogram hist)
    {
        // Get the maximum and minimum values from the histogram
        float minValue, maxValue;

        hist.GetMinMaxValue(out minValue, out maxValue);

        int xBins = hist.Bins.GetDimSize(0);  // Number of hue bins (x axis)
        int yBins = hist.Bins.GetDimSize(1);  // Number of saturation bins (y axis)

        // Create an image to visualize the histogram
        int   scaleHeight = 5, scaleWidth = 5;
        CvMat hist_img = new CvMat(yBins * scaleHeight, xBins * scaleWidth, TriColorMatrix);

        hist_img.Zero(); // Set all the pixels to black

        double binVal;
        int    _intensity;

        for (int h = 0; h < xBins; h++)
        {
            for (int s = 0; s < yBins; s++)
            {
                binVal     = Cv.QueryHistValue_2D(hist, h, s);
                _intensity = Cv.Round(binVal / maxValue * 255); // 0 to 255

                // Draw a rectangle (h, s) to (h+1, s+1)  (scaled by window size)
                //  The pixel value is the color of the histogram value at bin (h, s)
                hist_img.Rectangle(Cv.Point(h * scaleWidth, s * scaleHeight),
                                   Cv.Point((h + 1) * scaleWidth - 1, (s + 1) * scaleHeight - 1),
                                   Cv.RGB(_intensity, _intensity, _intensity),
                                   Cv.FILLED);
            }
        }


        Cv.ShowImage("HS Histogram", hist_img);
    }
    CvMat CalculateBackProjection(CvMat _image, CvHistogram hist)
    {
        CvMat _backProject = new CvMat(_image.Rows, _image.Cols, MonoColorMatrix);

        using (CvMat _imageHSV = ConvertToHSV(_image)) // Convert the image to HSV
            using (CvMat imgH = new CvMat(_image.Rows, _image.Cols, MonoColorMatrix))
                using (CvMat imgS = new CvMat(_image.Rows, _image.Cols, MonoColorMatrix))
                    using (CvMat imgV = new CvMat(_image.Rows, _image.Cols, MonoColorMatrix))
                    {
                        // Break image into H, S, V planes
                        // If the image were BGR, then it would split into B, G, R planes respectively
                        _imageHSV.CvtPixToPlane(imgH, imgS, imgV, null); // Cv.Split also does this

                        // Store HSV planes as an IplImage array to pass to openCV's hist function

                        // TODO:  Why can't BackProjection accept CvMat?
                        IplImage[] hsvPlanes = { Cv.GetImage(imgH), Cv.GetImage(imgS),
                                                 Cv.GetImage(imgV) };

                        hist.CalcBackProject(hsvPlanes, _backProject);
                    }
        return(_backProject);
    }
    // Creates an image from a 1D Histogram
    void Draw1DHistogram(CvMat _image)
    {
        float channelMax = 255;

        CvHistogram hist1 = CalculateOneChannelHistogram(_image, 0, channelMax);
        CvHistogram hist2 = CalculateOneChannelHistogram(_image, 1, channelMax);
        CvHistogram hist3 = CalculateOneChannelHistogram(_image, 2, channelMax);


        // Get the maximum and minimum values from the histogram
        float minValue, maxValue;

        hist1.GetMinMaxValue(out minValue, out maxValue);

        int hBins = hist1.Bins.GetDimSize(0);  // Number of bins


        // Create an image to visualize the histogram
        int   scaleWidth = 3, scaleHeight = 1;
        int   histWidth = hBins * imColorChannels * scaleWidth, histHeight = Mathf.FloorToInt(channelMax * scaleHeight);
        CvMat hist_img = new CvMat(histHeight, histWidth, TriColorMatrix);

        hist_img.Zero(); // Set all the pixels to black

        double binVal;
        int    _intensity;

        for (int h = 0; h < hBins; h++)
        {
            // Draw Channel 1
            binVal     = Cv.QueryHistValue_1D(hist1, h);
            _intensity = Cv.Round(binVal / maxValue * channelMax) * scaleHeight; // 0 to channelMax

            // Draw a rectangle (h, s) to (h+1, s+1)  (scaled by window size)
            //  The pixel value is the color of the histogram value at bin (h, s)
            hist_img.Rectangle(Cv.Point(h * imColorChannels * scaleWidth, histHeight),
                               Cv.Point(h * imColorChannels * scaleWidth + 1, histHeight - _intensity),
                               CvColor.Red, Cv.FILLED);

            // Draw Channel 2
            binVal     = Cv.QueryHistValue_1D(hist2, h);
            _intensity = Cv.Round(binVal / maxValue * channelMax) * scaleHeight; // 0 to channelMax

            // Draw a rectangle (h, s) to (h+1, s+1)  (scaled by window size)
            //  The pixel value is the color of the histogram value at bin (h, s)
            hist_img.Rectangle(Cv.Point(h * imColorChannels * scaleWidth + 2, histHeight * scaleHeight),
                               Cv.Point(h * imColorChannels * scaleWidth + 3, histHeight * scaleHeight - _intensity),
                               CvColor.Blue, Cv.FILLED);

            // Draw Channel 3
            binVal     = Cv.QueryHistValue_1D(hist3, h);
            _intensity = Cv.Round(binVal / maxValue * channelMax) * scaleHeight; // 0 to channelMax

            // Draw a rectangle (h, s) to (h+1, s+1)  (scaled by window size)
            //  The pixel value is the color of the histogram value at bin (h, s)
            hist_img.Rectangle(Cv.Point(h * imColorChannels * scaleWidth + 4, histHeight * scaleHeight),
                               Cv.Point(h * imColorChannels * scaleWidth + 5, histHeight * scaleHeight - _intensity),
                               CvColor.Green, Cv.FILLED);
        }

        Cv.ShowImage("Histogram", hist_img);
    }
    //  Takes an image and calculates its histogram in HSV color space
    // Color images have 3 channels (4 if you count alpha?)
    // Webcam captures them in (R)ed, (G)reen, (B)lue.
    // Convert to (H)ue, (S)aturation (V)alue to get better separation for thresholding
    CvHistogram CalculateHSVHistogram(CvMat _image)
    {
        // Hue, Saturation, Value or HSV is a color model that describes colors (hue or tint)
        // in terms of their shade (saturation or amount of gray)
        //	and their brightness (value or luminance).
        // For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255]

        // hue varies from 0 to 179, see cvtColor
        float hueMin = 0, hueMax = 179;

        float[] hueRanges = new float[2] {
            hueMin, hueMax
        };
        // saturation varies from 0 (black-gray-white) to
        // 255 (pure spectrum color)
        float satMin = 0, satMax = 255;

        float[] saturationRanges = new float[2] {
            satMin, satMax
        };

        float valMin = 0, valMax = 255;

        float[] valueRanges = new float[2] {
            valMin, valMax
        };

        float[][] ranges = { hueRanges, saturationRanges, valueRanges };

        // Note: You don't need to use all 3 channels for the histogram.
        int hueBins   = 32;               // Number of bins in the Hue histogram (more bins = narrower bins)
        int satBins   = 32;               // Number of bins in the Saturation histogram (more bins = narrower bins)
        int valueBins = 8;                // Number of bins in the Value histogram (more bins = narrower bins)

        float maxValue = 0, minValue = 0; // Minimum and maximum value of calculated histogram

        // Number of bins per histogram channel
        // If we use all 3 channels (H, S, V) then the histogram will have 3 dimensions.
        int[] hist_size = new int[] { hueBins, satBins, valueBins };

        CvHistogram hist = new CvHistogram(hist_size, HistogramFormat.Array, ranges, true);

        using (CvMat _imageHSV = ConvertToHSV(_image)) // Convert the image to HSV
                                                       // We could keep the image in B, G, R, A if we wanted to.
                                                       // Just split the channels into B, G, R planes

            using (CvMat imgH = new CvMat(_image.Rows, _image.Cols, MonoColorMatrix))
                using (CvMat imgS = new CvMat(_image.Rows, _image.Cols, MonoColorMatrix))
                    using (CvMat imgV = new CvMat(_image.Rows, _image.Cols, MonoColorMatrix))
                    {
                        // Break image into H, S, V planes
                        // If the image were RGB, then it would split into R, G, B planes respectively
                        _imageHSV.CvtPixToPlane(imgH, imgS, imgV, null); // Cv.Split also does this

                        // Store HSV planes as an IplImage array to pass to openCV's hist function
                        IplImage[] hsvPlanes = { Cv.GetImage(imgH), Cv.GetImage(imgS), Cv.GetImage(imgV) };

                        hist.Calc(hsvPlanes, false, null); // Call hist function (no accumulatation, no mask)

                        // Do we need to normalize??
                        hist.GetMinMaxValue(out minValue, out maxValue);
                        // Scale the histogram to unity height
                        hist.Normalize(_imageHSV.Width * _imageHSV.Height * hist.Dim * hueMax / maxValue);
                    }

        return(hist);  // Return the histogram
    }
    //  Takes an image and calculates its histogram for one channel.
    // Color images have 3 channels (4 if you count alpha?)
    // Webcam captures them in (R)ed, (G)reen, (B)lue.
    // Convert to (H)ue, (S)aturation (V)alue to get better separation for thresholding
    CvHistogram CalculateOneChannelHistogram(CvMat _image, int channelNum, float channelMax)
    {
        // Hue, Saturation, Value or HSV is a color model that describes colors (hue or tint)
        // in terms of their shade (saturation or amount of gray)
        //	and their brightness (value or luminance).
        // For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255]

        if (channelNum > imColorChannels)
        {
            Debug.LogError("Desired channel number " + channelNum + " is out of range.");
        }

        float channelMin = 0;

        float[] channelRanges = new float[2] {
            channelMin, channelMax
        };

        float[][] ranges = { channelRanges };

        // Note: You don't need to use all 3 channels for the histogram.
        int channelBins = 32;  // Number of bins in the Hue histogram (more bins = narrower bins)

        // Number of bins per histogram channel
        // If we use all 3 channels (H, S, V) then the histogram will have 3 dimensions.
        int[] hist_size = new int[] { channelBins };

        CvHistogram hist = new CvHistogram(hist_size, HistogramFormat.Array, ranges, true);

        using (CvMat _imageHSV = ConvertToHSV(_image)) // Convert the image to HSV
                                                       // We could keep the image in B, G, R, A if we wanted to.
                                                       // Just split the channels into B, G, R planes

            using (CvMat imgChannel = new CvMat(_imageHSV.Rows, _imageHSV.Cols, MonoColorMatrix))
            {
                // Break image into H, S, V planes
                // If the image were BGR, then it would split into B, G, R planes respectively

                switch (channelNum)
                {
                case 0:
                    _imageHSV.CvtPixToPlane(imgChannel, null, null, null);  // Cv.Split also does this
                    break;

                case 1:
                    _imageHSV.CvtPixToPlane(null, imgChannel, null, null);  // Cv.Split also does this
                    break;

                case 2:
                    _imageHSV.CvtPixToPlane(null, null, imgChannel, null);  // Cv.Split also does this
                    break;

                default:
                    Debug.LogError("Channel is out of range");
                    _imageHSV.CvtPixToPlane(imgChannel, null, null, null);  // Cv.Split also does this
                    break;
                }

                hist.Calc(Cv.GetImage(imgChannel), false, null); // Call hist function (no accumulatation, no mask)
            }

        return(hist);  // Return the histogram
    }
        public void colorConversion(string fileName)
        {
            srcImage   = Cv.LoadImage(fileName, LoadMode.Color);
            redImage   = new IplImage(srcImage.Size, srcImage.Depth, srcImage.NChannels);
            greenImage = new IplImage(srcImage.Size, srcImage.Depth, srcImage.NChannels);
            blueImage  = new IplImage(srcImage.Size, srcImage.Depth, srcImage.NChannels);

            for (var p = 0; p < srcImage.Height; p++)
            {
                for (var q = 0; q < srcImage.Width; q++)
                {
                    CvColor pixels = srcImage[p, q];
                    redImage[p, q] = new CvColor
                    {
                        R = (byte)(255 - pixels.R)
                    };
                    greenImage[p, q] = new CvColor
                    {
                        G = (byte)(255 - pixels.G)
                    };
                    blueImage[p, q] = new CvColor
                    {
                        B = (byte)(255 - pixels.B)
                    };
                }
            }

            Cv.SaveImage("red.jpg", redImage);
            Cv.SaveImage("green.jpg", greenImage);
            Cv.SaveImage("blue.jpg", blueImage);

            float[]   range  = { 0, 255 };
            float[][] ranges = { range };

            int histogramSize = 255;

            float minimumValue, maximumValue = 0;

            grayscaleRed = Cv.CreateImage(redImage.Size, BitDepth.U8, 1);
            Cv.CvtColor(redImage, grayscaleRed, ColorConversion.RgbToGray);

            grayscaleGreen = Cv.CreateImage(greenImage.Size, BitDepth.U8, 1);
            Cv.CvtColor(greenImage, grayscaleGreen, ColorConversion.RgbToGray);

            grayscaleBlue = Cv.CreateImage(blueImage.Size, BitDepth.U8, 1);
            Cv.CvtColor(blueImage, grayscaleBlue, ColorConversion.RgbToGray);

            CvHistogram histogramR = Cv.CreateHist(new int[] { histogramSize }, HistogramFormat.Array, ranges, true);

            Cv.CalcHist(grayscaleRed, histogramR);
            Cv.GetMinMaxHistValue(histogramR, out minimumValue, out maximumValue);
            Cv.Scale(histogramR.Bins, histogramR.Bins, ((double)redImage.Height) / maximumValue, 0);
            redImage.Set(CvColor.White);

            CvHistogram histogramG = Cv.CreateHist(new int[] { histogramSize }, HistogramFormat.Array, ranges, true);

            Cv.CalcHist(grayscaleGreen, histogramG);
            Cv.GetMinMaxHistValue(histogramG, out minimumValue, out maximumValue);
            Cv.Scale(histogramG.Bins, histogramG.Bins, ((double)greenImage.Height) / maximumValue, 0);
            greenImage.Set(CvColor.White);

            CvHistogram histogramB = Cv.CreateHist(new int[] { histogramSize }, HistogramFormat.Array, ranges, true);

            Cv.CalcHist(grayscaleBlue, histogramB);
            Cv.GetMinMaxHistValue(histogramB, out minimumValue, out maximumValue);
            Cv.Scale(histogramB.Bins, histogramB.Bins, ((double)blueImage.Height) / maximumValue, 0);
            blueImage.Set(CvColor.White);

            int bin_red   = Cv.Round((double)redImage.Width / histogramSize);
            int bin_green = Cv.Round((double)greenImage.Width / histogramSize);
            int bin_blue  = Cv.Round((double)blueImage.Width / histogramSize);


            int r;

            for (r = 0; r < histogramSize; r++)
            {
                redImage.Rectangle(new CvPoint(r * bin_red, grayscaleRed.Height), new CvPoint((r + 1) * bin_red, grayscaleRed.Height - Cv.Round(histogramR.Bins[r])), CvColor.Black, -1, LineType.Link8, 0);
            }

            int g;

            for (g = 0; g < histogramSize; g++)
            {
                greenImage.Rectangle(new CvPoint(g * bin_green, grayscaleGreen.Height), new CvPoint((r + 1) * bin_green, grayscaleGreen.Height - Cv.Round(histogramG.Bins[g])), CvColor.Black, -1, LineType.Link8, 0);
            }

            int b;

            for (b = 0; b < histogramSize; b++)
            {
                blueImage.Rectangle(new CvPoint(b * bin_blue, grayscaleBlue.Height), new CvPoint((r + 1) * bin_blue, grayscaleBlue.Height - Cv.Round(histogramR.Bins[b])), CvColor.Black, -1, LineType.Link8, 0);
            }

            Cv.SaveImage("histogramRed.jpg", redImage);
            Cv.SaveImage("histogramGreen.jpg", greenImage);
            Cv.SaveImage("histogramBlue.jpg", blueImage);
        }
        public IplImage BinarizerMethod_Hist(IplImage src)
        {
            bina = new IplImage(src.Size, BitDepth.U8, 1);
            gray = this.GrayScale(src);

            int area = 200;
            int num  = 0;

            int row   = (src.Width % area == 0) ? (int)(src.Width / area) : (int)(src.Width / area + 1);
            int col   = (src.Height % area == 0) ? (int)(src.Height / area) : (int)(src.Height / area + 1);
            int count = row * col;

            float[]    data      = new float[count];
            IplImage[] piece     = new IplImage[count];
            CvRect[]   piece_roi = new CvRect[count];

            for (int x = 0; x < src.Width; x = x + area)
            {
                for (int y = 0; y < src.Height; y = y + area)
                {
                    CvRect roi = new CvRect
                    {
                        X      = x,
                        Y      = y,
                        Width  = area,
                        Height = area
                    };

                    if (roi.X + roi.Width > src.Width)
                    {
                        roi.Width = area - ((roi.X + roi.Width) - src.Width);
                    }
                    if (roi.Y + roi.Height > src.Height)
                    {
                        roi.Height = area - ((roi.Y + roi.Height) - src.Height);
                    }

                    gray.SetROI(roi);
                    piece[num] = new IplImage(gray.ROI.Size, BitDepth.U8, 1);
                    Cv.Copy(gray, piece[num]);
                    gray.ResetROI();

                    //히스토그램 계산//
                    int[]       size = { area };
                    CvHistogram hist = new CvHistogram(size, HistogramFormat.Array);
                    Cv.CalcHist(piece[num], hist);

                    float minValue, maxValue;
                    hist.GetMinMaxValue(out minValue, out maxValue);

                    int highlevel = 0;
                    for (int i = 0; i < area; i++)
                    {
                        if (maxValue == hist.Bins[i].Val0)
                        {
                            highlevel = i;
                        }
                    }

                    piece_roi[num] = roi;
                    data[num]      = highlevel;
                    num++;
                }
            }

            CvMat kernel = new CvMat(row, col, MatrixType.F32C1, data);

            Cv.Normalize(kernel, kernel, 255, 0, NormType.C);

            for (int r = 0; r < count; r++)
            {
                Cv.Threshold(piece[r], piece[r], kernel[r], 255, ThresholdType.Otsu);

                Cv.SetImageROI(bina, piece_roi[r]);
                Cv.Copy(piece[r], bina);
                bina.ResetROI();
            }

            //37강 - 윈도우 창//
            CvWindow win = new CvWindow("window", WindowMode.StretchImage, src);

            win.Resize(640, 480);
            win.Move(100, 0);
            win.ShowImage(piece[0]);
            win.Close();

            new CvWindow(piece[0]).Move(0, 0);
            new CvWindow(piece[1]).Move(0, 200);
            new CvWindow(piece[2]).Move(0, 400);
            //37강 - 윈도우 창//

            return(bina);
        }
Exemple #20
0
        private double CalculateHistogramDistance(string jpg_path1, string jpg_path2)
        {
            int i, sch = 0;

            float[]   range_0 = { 0, 256 };
            float[][] ranges = { range_0 };
            double    tmp, dist = 0;
            IplImage  src_img1, src_img2;

            IplImage[] dst_img1 = new IplImage[4];
            IplImage[] dst_img2 = new IplImage[4];

            CvHistogram[] hist1 = new CvHistogram[4];
            CvHistogram   hist2;

            src_img1 = IplImage.FromFile(jpg_path1, LoadMode.AnyDepth | LoadMode.AnyColor);

            // チャンネル数分の画像領域を確保
            sch = src_img1.NChannels;
            for (i = 0; i < sch; i++)
            {
                dst_img1[i] = Cv.CreateImage(Cv.Size(src_img1.Width, src_img1.Height), src_img1.Depth, 1);
            }
            // ヒストグラム構造体を確保
            int[] nHisSize = new int[1];
            nHisSize[0] = 256;
            hist1[0]    = Cv.CreateHist(nHisSize, HistogramFormat.Array, ranges, true);

            // 入力画像がマルチチャンネルの場合,画像をチャンネル毎に分割
            if (sch == 1)
            {
                Cv.Copy(src_img1, dst_img1[0]);
            }
            else
            {
                Cv.Split(src_img1, dst_img1[0], dst_img1[1], dst_img1[2], dst_img1[3]);
            }

            for (i = 0; i < sch; i++)
            {
                Cv.CalcHist(dst_img1[i], hist1[i], false);
                Cv.NormalizeHist(hist1[i], 10000);
                if (i < 3)
                {
                    Cv.CopyHist(hist1[i], ref hist1[i + 1]);
                }
            }

            Cv.ReleaseImage(src_img1);

            src_img2 = IplImage.FromFile(jpg_path2, LoadMode.AnyDepth | LoadMode.AnyColor);

            // 入力画像のチャンネル数分の画像領域を確保
            for (i = 0; i < sch; i++)
            {
                dst_img2[i] = Cv.CreateImage(Cv.Size(src_img2.Width, src_img2.Height), src_img2.Depth, 1);
            }

            // ヒストグラム構造体を確保
            nHisSize[0] = 256;
            hist2       = Cv.CreateHist(nHisSize, HistogramFormat.Array, ranges, true);

            // 入力画像がマルチチャンネルの場合,画像をチャンネル毎に分割
            if (sch == 1)
            {
                Cv.Copy(src_img2, dst_img2[0]);
            }
            else
            {
                Cv.Split(src_img2, dst_img2[0], dst_img2[1], dst_img2[2], dst_img2[3]);
            }

            try
            {
                dist = 0.0;

                // ヒストグラムを計算,正規化して,距離を求める
                for (i = 0; i < sch; i++)
                {
                    Cv.CalcHist(dst_img2[i], hist2, false);
                    Cv.NormalizeHist(hist2, 10000);
                    tmp   = Cv.CompareHist(hist1[i], hist2, HistogramComparison.Bhattacharyya);
                    dist += tmp * tmp;
                }
                dist = Math.Sqrt(dist);

                Cv.ReleaseHist(hist2);
                Cv.ReleaseImage(src_img2);
            }
            catch (OpenCVException ex)
            {
                Console.WriteLine("Error : " + ex.Message);
            }

            return(dist);
        }
Exemple #21
0
        // NOTE : Also seems not well written and craves optimization at places. P.A.N.A.R.G.O.
        // => frame = 8 bit greyscale CvMat
        static public void ContrastEnhancement(CvMat frame)
        {
            //CvMat originalFrame = frame; // return this if cannot enhance
            //if (frame.ElemType != MatrixType.U8C1)
            //	frame = MatOps.Convert(frame, MatrixType.U8C1, 1 / 255.0 );

            /////original histogram
            const int HistBinSize = 256;

            int[] histSizes = new int[1];
            histSizes[0] = HistBinSize;
            CvHistogram hist = new CvHistogram(histSizes, HistogramFormat.Array);

            Cv.CalcArrHist(frame, hist, false);               // size = 256 implied

            CvHistogram newHist    = MatOps.CopyHistogram(hist);
            CvArr       newHistBin = newHist.Bins;

            //double[] origVals = new double[hist.Bins.GetDims( 0 )];
            List <double> origVals = new List <double>(HistBinSize);

            for (int i = 0; i < HistBinSize; i++)
            {
                double elem = newHistBin.GetReal1D(i);
                if (elem != 0)
                {
                    origVals.Add(elem);
                }
            }

            // FIX : See no need for histL, since we have origVals
            //////histogram with only nonzero bins
            //CvMat histL = new CvMat( imageRows, imageCols, MatrixType.F32C1, new CvScalar( 0 ) );
            //for (i = 0; i < origVals.size(); i++)
            //	histL.at<float>( i, 0 ) = origVals.at( i );

            List <double> peakValues = new List <double>(HistBinSize);             //std::vector<int> peakValues;

            //////////3 bin search window
            for (int i = 1; i < origVals.Count - 2; ++i)
            {
                double elem = origVals[i];
                if (elem > origVals[i - 1] && elem > origVals[i + 1])
                {
                    peakValues.Add(elem);
                }
            }

            if (peakValues.Count == 0)
            {
                //Console.Out.WriteLine( "Cannot enhance" );
                return;                 // cannot enhance?
            }

            //////Upper threshold
            double threshUP = 0;

            for (int i = 0; i < peakValues.Count; ++i)
            {
                threshUP += peakValues[i];
            }
            threshUP /= peakValues.Count;

            //////Lower threshold
            double threshDOWN = Math.Min((frame.Cols * frame.Rows), threshUP * origVals.Count) / 256.0;
            //Console.Out.WriteLine( "Enhance thresholds " + threshUP + "/" + threshDOWN );

            //////histogram reconstruction
            CvArr histBins = hist.Bins;

            for (int i = 0; i < HistBinSize; ++i)
            {
                double histElem = histBins.GetReal1D(i);
                if (histElem > threshUP)
                {
                    histBins.SetReal1D(i, threshUP);
                }
                else if (histElem <= threshUP && histElem >= threshDOWN)
                {
                    continue;
                }
                else if (histElem < threshDOWN && histElem > 0)
                {
                    histBins.SetReal1D(i, threshDOWN);
                }
                else if (histElem == 0)
                {
                    continue;
                }
            }
            // accumulated values(?)
            double[] accVals = new double[HistBinSize];             //std::vector<int> accVals;
            accVals[0] = (histBins.GetReal1D(0));
            for (int i = 1; i < HistBinSize; ++i)
            {
                accVals[i] = (accVals[i - 1] + histBins[i]);
            }

            byte[] lookUpTable = new byte[HistBinSize];             //cv::Mat lookUpTable = cv::Mat::zeros( hist.size(), CV_8UC1 );
            for (int i = 0; i < HistBinSize; ++i)
            {
                lookUpTable[i] = (byte)(255.0 * accVals[i] / accVals[255]);
            }

            // assign computed values to input frame
            //Console.Out.Write( "Enhance-->" );
            for (int i = 0; i < frame.Cols; ++i)
            {
                for (int j = 0; j < frame.Rows; ++j)
                {
                    // there is NO mask, thus no need to check for; was: "if (mask.data)..."
                    byte oldValue = (byte)frame.Get2D(j, i);
                    byte newValue = lookUpTable[oldValue];
                    //if ((newValue <1 || newValue > 254) && (newValue != oldValue)) Console.Out.Write( oldValue + " " + newValue + "|");
                    frame.Set2D(j, i, newValue);
                    //frame.SetReal2D( j, i, lookUpTable[ (int)(255.0 * frame.GetReal2D( j, i )) ] / 255.0);
                }
            }
            //Console.Out.WriteLine();

            //frame = MatOps.Convert( frame, MatrixType.U8C1, 255.0 );
        }
    // Update and OnGUI are the main loops
    void Update()
    {
        if (DrawThresholdImageFlag)
        {
            DrawThresholdImage(videoSourceImage);
        }

        FindObjectScreenPosition();

        if (_webcamTexture.isPlaying)
        {
            if (_webcamTexture.didUpdateThisFrame)
            {
                //convert Unity 2D texture from webcam to CvMat
                Texture2DToCvMat();

                // Do some image processing with OpenCVSharp on this image frame
                ProcessImage(videoSourceImage);
            }
        }
        else
        {
            Debug.Log("Can't find camera!");
        }

        if (Input.GetKeyDown(KeyCode.H))  // "h" key turns histogram screen on/off
        {
            histoWindowFlag = !histoWindowFlag;
        }


        if (trackFlag)
        {
            if (Input.GetKeyDown(KeyCode.B))  // "b" key turns back projection on/off
            {
                backprojWindowFlag = !backprojWindowFlag;
            }
            if (Input.GetKeyDown(KeyCode.T))  // "t" key turns tracking openCV window on
            {
                trackWindowFlag = !trackWindowFlag;
            }

            // Move an external game object based on the ROI being tracked
            if (gameObjectTracker)
            {
                ROIScreenToGameObject(rotatedBoxToTrack, gameObjectTracker);
            }
        }

        if (Input.GetMouseButtonDown(1))
        { // Right mouse button
            Debug.Log("Tracking off");
            trackFlag    = false;
            _mouseIsDown = false;
        }
        else if (Input.GetMouseButtonDown(0))
        {  // Left mouse button
            if (!_mouseIsDown)
            {
                _mouseDownPos = Input.mousePosition;
                trackFlag     = false;
            }

            _mouseIsDown = true;
        }


        if (Input.GetMouseButtonUp(0))
        {  // Left mouse button is up
            // If mouse went from down to up, then update the region of interest using the box
            if (_mouseIsDown)
            {
                // Calculate the histogram for the selected region of interest (ROI)
                _rectToTrack = CheckROIBounds(ConvertRect2CvRect(MakePixelBox(_mouseDownPos, _mouseLastPos)));

                if (DisplayROIFlag)
                {
                    // Draw the region of interest to track
                    DrawROIBox(videoSourceImage);
                }

                // Use Hue/Saturation histogram (not just the Hue dimension)
                _histogramToTrack = CalculateHSVHistogram(GetROI(videoSourceImage, _rectToTrack));

                // Use Hue channel histogram only
                //_histogramToTrack = CalculateOneChannelHistogram (GetROI (videoSourceImage, _rectToTrack), 0, 179);

                lastPosition = new CvPoint(Mathf.FloorToInt(_rectToTrack.X), Mathf.FloorToInt(_rectToTrack.Y));
                InitializeKalmanFilter();

                trackFlag = true;
            }

            _mouseIsDown = false;
        }
    }