Пример #1
0
        /// <summary>
        /// 反向投影(3維),需搭配3維的直方圖計算
        /// </summary>
        /// <param name="template">樣板值方圖</param>
        /// <param name="observedSrcImg">要比對觀察的影像</param>
        /// <param name="isNormalized">是否要標準化</param>
        /// <param name="factor">標準化參數,預設1200000d</param>
        /// <returns>回除灰階的觀察影像(越白代表匹配的顏色越高)</returns>
        public static Image <Gray, Byte> HSVBackProject(DenseHistogram template, Image <Bgr, Byte> observedSrcImg, bool isNormalized = true, double factor = 1200000d)
        {
            try
            {
                DenseHistogram templateHist = new DenseHistogram(new int[] { template.BinDimension[0].Size, template.BinDimension[1].Size, template.BinDimension[2].Size }, new RangeF[] { new RangeF(0, h_max_range), new RangeF(0, s_max_range), new RangeF(0, v_max_range) });
                template.Copy(templateHist);
                Image <Bgr, Byte> observedImg     = observedSrcImg.Copy();
                IntPtr            hsv             = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(observedImg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);
                IntPtr            h_plane         = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(observedImg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1);
                IntPtr            s_plane         = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(observedImg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1);
                IntPtr            v_plane         = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(observedImg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1);
                IntPtr[]          observed_planes = new IntPtr[3] {
                    h_plane, s_plane, v_plane
                };
                //Image<Gray, Byte> h_planeImg = IplImagePointerToEmgucvImage<Gray, Byte>(h_plane);
                //Image<Gray, Byte> s_planeImg = IplImagePointerToEmgucvImage<Gray, Byte>(s_plane);
                CvInvoke.cvCvtColor(observedImg, hsv, Emgu.CV.CvEnum.COLOR_CONVERSION.CV_BGR2HSV);
                CvInvoke.cvSplit(hsv, h_plane, s_plane, v_plane, System.IntPtr.Zero); // 分离的单通道数组d
                if (isNormalized)
                {
                    templateHist.Normalize(factor);
                }

                IntPtr backProj = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(observedImg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1);
                CvInvoke.cvZero(backProj);
                CvInvoke.cvCalcBackProject(observed_planes, backProj, templateHist);

                return(EmguFormatConvetor.IplImagePointerToEmgucvImage <Gray, Byte>(backProj));
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(ex.Message);
            }
        }
Пример #2
0
        /// <summary>
        /// 等化影像
        /// </summary>
        /// <param name="srcImg">要等化的影像</param>
        /// <returns>回傳等化過的影像</returns>
        public static Image <Bgr, Byte> EqualizationImage(Image <Bgr, Byte> srcImg)
        {
            IntPtr dstImg     = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(srcImg), IPL_DEPTH.IPL_DEPTH_8U, 3);
            IntPtr redImage   = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(srcImg), IPL_DEPTH.IPL_DEPTH_8U, 1);
            IntPtr greenImage = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(srcImg), IPL_DEPTH.IPL_DEPTH_8U, 1);
            IntPtr blueImage  = CvInvoke.cvCreateImage(CvInvoke.cvGetSize(srcImg), IPL_DEPTH.IPL_DEPTH_8U, 1);

            CvInvoke.cvSplit(srcImg, blueImage, greenImage, redImage, IntPtr.Zero);
            CvInvoke.cvEqualizeHist(blueImage, blueImage);
            CvInvoke.cvEqualizeHist(greenImage, greenImage);
            CvInvoke.cvEqualizeHist(redImage, redImage);
            CvInvoke.cvMerge(blueImage, greenImage, redImage, IntPtr.Zero, dstImg);
            return(EmguFormatConvetor.IplImagePointerToEmgucvImage <Bgr, Byte>(dstImg));
        }
Пример #3
0
        /// <summary>
        /// 2D值方圖(色調與飽和度) 的繪製,使用emgucv提供的cvInvoke去調用opencv的函式
        /// 繪製與範例的值方圖一致目前先採用
        /// </summary>
        /// <param name="histDense"></param>
        /// <returns>回傳繪製值方圖的影像,直接顯示即可</returns>
        public static Image <Bgr, Byte> Generate2DHistogramImgForDraw(DenseHistogram histDense)
        {
            try
            {
                float max_value = 0.0f;
                int[] a1        = new int[100];
                int[] b1        = new int[100];
                float ax        = 0;
                int   h_bins    = histDense.BinDimension[0].Size;
                int   s_bins    = histDense.BinDimension[1].Size;

                //1.使用Intptr
                // CvInvoke.cvGetMinMaxHistValue(histPtr, ref ax, ref max_value, a1, b1);

                //2.emgucv的DenseHistogram資料格式也可使用cvInvoke的openCV函式
                CvInvoke.cvGetMinMaxHistValue(histDense, ref ax, ref max_value, a1, b1);

                /* 设置直方图显示图像 */
                int height = 300;
                int width;
                //如果設定的bins超過視窗設定的顯示範圍,另外給予可以符合用額外的彈出視窗顯示的值
                if (h_bins * s_bins > 800)
                {
                    width = h_bins * s_bins * 2;
                }
                else
                {
                    width = 800;
                }

                IntPtr hist_img = CvInvoke.cvCreateImage(new System.Drawing.Size(width, height), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);
                CvInvoke.cvZero(hist_img);

                /* 用来进行HSV到RGB颜色转换的临时单位图像 */
                IntPtr hsv_color = CvInvoke.cvCreateImage(new System.Drawing.Size(1, 1), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);
                IntPtr rgb_color = CvInvoke.cvCreateImage(new System.Drawing.Size(1, 1), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);
                int    bin_w     = width / (h_bins * s_bins);

                for (int h = 0; h < h_bins; h++)
                {
                    for (int s = 0; s < s_bins; s++)
                    {
                        int i = h * s_bins + s;
                        /* 获得直方图中的统计次数,计算显示在图像中的高度 */
                        //
                        //取得值方圖的數值位置,以便之後存成檔案
                        //1.Intptr
                        //double bin_val = CvInvoke.cvQueryHistValue_2D(histPtr, h, s);

                        //2.DenseHistogram
                        double bin_val   = CvInvoke.cvQueryHistValue_2D(histDense, h, s);
                        int    intensity = (int)System.Math.Round(bin_val * height / max_value);

                        /* 获得当前直方图代表的颜色,转换成RGB用于绘制 */
                        CvInvoke.cvSet2D(hsv_color, 0, 0, new Emgu.CV.Structure.MCvScalar(h * 180.0f / h_bins, s * 255.0f / s_bins, 255, 0));
                        CvInvoke.cvCvtColor(hsv_color, rgb_color, COLOR_CONVERSION.CV_HSV2BGR);
                        Emgu.CV.Structure.MCvScalar color = CvInvoke.cvGet2D(rgb_color, 0, 0);
                        CvInvoke.cvRectangle(hist_img, new System.Drawing.Point(i * bin_w, height), new System.Drawing.Point((i + 1) * bin_w, height - intensity), color, -1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0);
                    }
                }

                /*
                 *使用openCV函式繪製
                 * CvInvoke.cvNamedWindow("Source");
                 * CvInvoke.cvShowImage("Source", this.srcImage);
                 * CvInvoke.cvNamedWindow("H-S Histogram");
                 * CvInvoke.cvShowImage("H-S Histogram", hist_img);
                 * CvInvoke.cvWaitKey(0);
                 * */
                return(EmguFormatConvetor.IplImagePointerToEmgucvImage <Bgr, Byte>(hist_img));
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(ex.Message);
            }
        }
Пример #4
0
        //////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// drawing hue color still have problem
        /// 1D值方圖(色調) 的繪製,使用emgucv提供的cvInvoke去調用opencv的函式
        /// 繪製與範例的值方圖一致目前先採用
        /// </summary>
        /// <param name="histDense"></param>
        /// <returns>回傳繪製值方圖的影像,直接顯示即可</returns>
        public static Image <Bgr, Byte> Generate1DHistogramImgForDraw(DenseHistogram histDense)
        {
            try
            {
                float max_value = 0.0f;
                int[] a1        = new int[100];
                int[] b1        = new int[100];
                float ax        = 0;
                int   h_bins    = histDense.BinDimension[0].Size;

                //1.使用Intptr
                // CvInvoke.cvGetMinMaxHistValue(histPtr, ref ax, ref max_value, a1, b1);

                //2.emgucv的DenseHistogram資料格式也可使用cvInvoke的openCV函式
                CvInvoke.cvGetMinMaxHistValue(histDense, ref ax, ref max_value, a1, b1);

                /* 取最大的顏色的位置 並換成RGB
                 * foreach (int index in a1)
                 * {
                 *  Console.WriteLine("location="+index+",H Color = "+ HueToBgr(index * 180.0d / h_bins));
                 * }
                 * */
                /* 设置直方图显示图像 */
                int    height   = 240;
                int    width    = 800;
                IntPtr hist_img = CvInvoke.cvCreateImage(new System.Drawing.Size(width, height), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);
                CvInvoke.cvZero(hist_img);

                /* 用来进行HSV到RGB颜色转换的临时单位图像 */
                IntPtr hsv_color = CvInvoke.cvCreateImage(new System.Drawing.Size(1, 1), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);
                IntPtr rgb_color = CvInvoke.cvCreateImage(new System.Drawing.Size(1, 1), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);
                int    bin_w     = width / (h_bins);

                for (int h = 0; h < h_bins; h++)
                {
                    /* 获得直方图中的统计次数,计算显示在图像中的高度 */
                    //
                    //取得值方圖的數值位置,以便之後存成檔案
                    //2.DenseHistogram
                    double bin_val   = CvInvoke.cvQueryHistValue_1D(histDense, h);
                    int    intensity = (int)System.Math.Round(bin_val * height / max_value);

                    /* 获得当前直方图代表的hue颜色,转换成RGB用于绘制 */
                    CvInvoke.cvRectangle(hist_img, new System.Drawing.Point(h * bin_w, height),
                                         new System.Drawing.Point((h + 1) * bin_w, height - intensity),
                                         HueToBgr(h * 180.0d / h_bins), -1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0);
                }

                /*
                 *使用openCV函式繪製
                 * CvInvoke.cvNamedWindow("Source");
                 * CvInvoke.cvShowImage("Source", this.srcImage);
                 * CvInvoke.cvNamedWindow("H-S Histogram");
                 * CvInvoke.cvShowImage("H-S Histogram", hist_img);
                 * CvInvoke.cvWaitKey(0);
                 * */
                return(EmguFormatConvetor.IplImagePointerToEmgucvImage <Bgr, Byte>(hist_img));
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(ex.Message);
            }
        }