/// <summary>
        /// Using depth first search to find all non-white connected components.
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="visited"></param>
        /// <param name="ccResult"></param>
        public static void DFS(int width, int height, ref bool[,] visited, ConnectedComponent ccResult, Bitmap sourceImage)
        {
            int i = 0;
            int j = 0;

            try
            {
                for (i = -1; i <= 1; i++)
                {
                    for (j = -1; j <= 1; j++)
                    {
                        if (!(i == 0 && j == 0) &&
                            width + i >= 0 && width + i < sourceImage.Width &&
                            height + j >= 0 && height + j < sourceImage.Height &&
                            !visited[width + i, height + j] &&
                            calDiff(sourceImage.GetPixel(width, height), sourceImage.GetPixel(width + i, height + j)) <= ConfigParameters.DiffThreshold)
                        {
                            visited[width + i, height + j] = true;

                            ccResult.PointSet.Add(new iPoint(width + i, height + j));

                            DFS(width + i, height + j, ref visited, ccResult, sourceImage);
                        }
                    }
                }
            }
            catch (Exception ecc)
            {
                throw new Exception(ecc.Message);
            }
        }
        /// <summary>
        /// Find all connected-components in the image and return related information.
        /// </summary>
        /// <param name="sourceImage"></param>
        /// <returns></returns>
        public static List<ConnectedComponent> findAllConnectedComponents(Bitmap sourceImage)
        {
            int i = 0, j = 0;

            int width = sourceImage.Width;
            int height = sourceImage.Height;

            // The array which tells whether the point at position[i,j] has been visited.
            bool[,] visited = new bool[width, height];

            List<ConnectedComponent> ccResult = new List<ConnectedComponent>();

            try
            {
                for (i = 0; i < width; i++)
                {
                    for (j = 0; j < height; j++)
                    {
                        if (!judgeWhitePoint(sourceImage.GetPixel(i, j)) && !visited[i, j])
                        {
                            visited[i, j] = true;

                            ConnectedComponent currentCC = new ConnectedComponent();

                            currentCC.PointSet.Add(new iPoint(i, j));
                            try
                            {
                                DFS(i, j, ref visited, currentCC, sourceImage);
                            }
                            catch (Exception ea)
                            {
                                throw new Exception(ea.Message);
                            }

                            FormatConnectedComponent(currentCC);

                            ccResult.Add(currentCC);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
            return ccResult;
        }
        /// <summary>
        /// Merge different connected components into one.
        /// </summary>
        /// <param name="cc1"></param>
        /// <param name="cc2"></param>
        /// <returns></returns>
        public static ConnectedComponent mergeConnectedComponents(List<ConnectedComponent> cc)
        {
            // If there are only one element in the list, return the element directly.
            if (cc.Count == 1)
            {
                return cc[0];
            }

            ConnectedComponent ccRet = new ConnectedComponent();

            int minWidth = int.MaxValue, minHeight = int.MaxValue;
            int maxWidth = int.MinValue, maxHeight = int.MinValue;

            foreach (ConnectedComponent ccI in cc)
            {
                minWidth = ccI.Left_Top.Width_Position < minWidth ? ccI.Left_Top.Width_Position : minWidth;
                minHeight = ccI.Left_Top.Height_Position < minHeight ? ccI.Left_Top.Height_Position : minHeight;

                maxWidth = ccI.Right_Bottom.Width_Position > maxWidth ? ccI.Right_Bottom.Width_Position : maxWidth;
                maxHeight = ccI.Right_Bottom.Height_Position > maxHeight ? ccI.Right_Bottom.Height_Position : maxHeight;

                foreach (iPoint ponit in ccI.PointSet)
                {
                    ccRet.PointSet.Add(ponit);
                }
            }
            ccRet.Left_Top = new iPoint(minWidth, minHeight);
            ccRet.Right_Bottom = new iPoint(maxWidth, maxHeight);

            return ccRet;
        }
        /// <summary>
        /// Judge whether two connected components are similar in color.
        /// </summary>
        /// <param name="c1"></param>
        /// <param name="c2"></param>
        /// <returns></returns>
        private static bool judgeConnectedComponentsSimilar(ConnectedComponent c1, ConnectedComponent c2, Bitmap sourceImage)
        {
            bool flag = true;

            for (int i = 0; i < c1.PointSet.Count && flag; i++)
            {
                for (int j = 0; j < c2.PointSet.Count && flag; j++)
                {
                    if (calDiff(
                                sourceImage.GetPixel(c1.PointSet[i].Width_Position, c1.PointSet[i].Height_Position),
                                sourceImage.GetPixel(c2.PointSet[j].Width_Position, c2.PointSet[j].Height_Position)
                                ) > Config.ConfigParameters.DiffThreshold
                       )
                    {
                        flag = false;
                    }
                }
            }

            return flag;
        }
        /// <summary>
        /// Judge whether two connected components are near enough.
        /// </summary>
        /// <param name="c1"></param>
        /// <param name="c2"></param>
        /// <returns></returns>
        private static bool judgeConnectedComponentsNear(ConnectedComponent c1, ConnectedComponent c2)
        {
            double distance = calculateDistanceBetweenConnectedComponents(c1, c2);

            return distance - Config.ConfigParameters.DistanceThreshold < 0.00001 ? true : false;
        }
        /// <summary>
        /// Calculate the size of certain connected component.
        /// </summary>
        /// <param name="cc"></param>
        /// <returns></returns>
        private static int calConnectedComponentsSize(ConnectedComponent cc)
        {
            int width = cc.Right_Bottom.Width_Position - cc.Left_Top.Width_Position;
            int height = cc.Right_Bottom.Height_Position - cc.Left_Top.Height_Position;

            return width * height;
        }
        /// <summary>
        /// Calculate the distance of two connected components.
        /// </summary>
        /// <param name="c1"></param>
        /// <param name="c2"></param>
        /// <returns></returns>
        private static double calculateDistanceBetweenConnectedComponents(ConnectedComponent c1, ConnectedComponent c2)
        {
            double tmp = 0;
            double distance = double.MaxValue;

            foreach (iPoint point1 in c1.PointSet)
            {
                foreach (iPoint point2 in c2.PointSet)
                {
                    tmp = calPointDistance(point1, point2);
                    if (tmp < distance)
                    {
                        distance = tmp;
                    }
                }
            }

            return distance;
        }
        /// <summary>
        /// According to the point information to find the left-top and right-bottom point.
        /// </summary>
        /// <param name="currentCC"></param>
        private static void FormatConnectedComponent(ConnectedComponent currentCC)
        {
            int minWidth = int.MaxValue;
            int maxWidth = int.MinValue;
            int minHeight = int.MaxValue;
            int maxHeight = int.MinValue;

            foreach (iPoint point in currentCC.PointSet)
            {
                if (point.Width_Position < minWidth)
                {
                    minWidth = point.Width_Position;
                }
                if (point.Width_Position > maxWidth)
                {
                    maxWidth = point.Width_Position;
                }
                if (point.Height_Position < minHeight)
                {
                    minHeight = point.Height_Position;
                }
                if (point.Height_Position > maxHeight)
                {
                    maxHeight = point.Height_Position;
                }
            }

            currentCC.Left_Top = new iPoint(minWidth, minHeight);
            currentCC.Right_Bottom = new iPoint(maxWidth, maxHeight);
        }
        /// <summary>
        /// Write one connected component to certain bmp image.
        /// </summary>
        /// <param name="ccImage"></param>
        /// <param name="sourceImage"></param>
        public static void write_Single_Connected_Component_To_Bmp(int tIndex, int index, ConnectedComponent ccImage, Bitmap sourceImage)
        {
            int width = ccImage.Right_Bottom.Width_Position - ccImage.Left_Top.Width_Position;
            int height = ccImage.Right_Bottom.Height_Position - ccImage.Left_Top.Height_Position;

            Bitmap ccBmp = new Bitmap(width + 1, height + 1, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            Graphics ccGraphics = Graphics.FromImage(ccBmp);

            // Set the background color as white.
            ccGraphics.Clear(Color.FromArgb(255, 255, 255));

            ccGraphics.Dispose();

            foreach (iPoint point in ccImage.PointSet)
            {
                ccBmp.SetPixel(point.Width_Position - ccImage.Left_Top.Width_Position,
                               point.Height_Position - ccImage.Left_Top.Height_Position,
                               sourceImage.GetPixel(point.Width_Position, point.Height_Position)
                );
            }

            ccBmp.Save(ConfigParameters.CC_Image_Bmp_Path + tIndex.ToString() + "_" + index.ToString() + ".bmp");
        }
Ejemplo n.º 10
0
 public ConnectedComponent(ConnectedComponent _cc)
 {
     iniParameter(_cc.Left_Top, _cc.Right_Bottom, _cc.PointSet);
 }