Beispiel #1
0
        /// <summary>ラベルの包含関係を調べる</summary>
        /// <param name="label">ラベリングデータ</param>
        /// <returns>包含関係</returns>
        public int[][] GetInclusionLink(LabelStructure label)
        {
            logWriter.Write("ラベルの包含関係を調べます");

            if (label == null)
            {
                logWriter.WriteError("ラベル情報がありません");
                logWriter.WriteError("処理を中止します");
                return(null);
            }

            int[][] link = new int[label.Max - label.Min + 1][];

            using (PrograssWindow pw = new PrograssWindow("包含検査", label.Max - label.Min + 1))
            {
                Parallel.For(label.Min, label.Max + 1, (n, state) =>
                {
                    link[n - label.Min] = GetInclusionNumber(label, n);
                    pw.Add();
                });

                pw.Join();
            }

            logWriter.Write("ラベルの包含関係を調べました");
            return(link);
        }
Beispiel #2
0
        /// <summary>ラベルの包含関係を調べる</summary>
        /// <param name="label">ラベリングデータ</param>
        /// <param name="token">キャンセルトークン</param>
        /// <returns>包含関係</returns>
        public int[][] GetInclusionLink(LabelStructure label, CancellationTokenSource token)
        {
            logWriter.Write("ラベルの包含関係を調べます");

            if (label == null)
            {
                logWriter.WriteError("ラベル情報がありません");
                logWriter.WriteError("処理を中止します");
                return(null);
            }

            label.SetMinMax();
            int[][] link = new int[label.Max - label.Min + 1][];

            using (PrograssWindow pw = new PrograssWindow("包含検査", label.Max - label.Min + 1))
            {
                Parallel.For(label.Min, label.Max + 1, (n, state) =>
                {
                    if (token.IsCancellationRequested)
                    {
                        state.Break();
                    }
                    link[n - label.Min] = GetInclusionNumber3(label, n);
                    pw.Add();
                });
            }

            logWriter.Write("ラベルの包含関係を調べました");
            return(link);
        }
Beispiel #3
0
        /// <summary>深さ情報を持った画像を保存する</summary>
        /// <param name="image">保存したい画像</param>
        /// <param name="depth">画像の深さデータ</param>
        /// <param name="path">保存したい場所</param>
        public void Save(Bitmap image, LabelStructure depth, string path)
        {
            logWriter.Write("三次元画像を保存します");

            try
            {
                using (StreamWriter sw = new StreamWriter(path))
                {
                    sw.WriteLine(image.Width + " " + image.Height);
                    for (int y = 0; y < image.Height; y++)
                    {
                        for (int x = 0; x < image.Width; x++)
                        {
                            Color c = image.GetPixel(x, y);
                            sw.WriteLine(c.R + " " + c.G + " " + c.B + " " + depth[y, x]);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logWriter.WriteError("三次元画像の保存に失敗しました");
                logWriter.WriteError(ex.ToString());
                return;
            }

            logWriter.Write("三次元画像を保存しました");
            logWriter.Write("path=" + path);
        }
Beispiel #4
0
        /// <summary>ラベル情報を視覚化する</summary>
        /// <param name="label">視覚化したいラベルデータ</param>
        /// <returns>視覚化された画像<see cref="Bitmap"/></returns>
        private Bitmap GetLabelImage(LabelStructure label)
        {
            logWriter.Write("ラベルデータの画像作成を行います");

            if (label == null)
            {
                logWriter.WriteError("ラベルデータが存在しません");
                logWriter.WriteError("画像作成を中止します");
                return(null);
            }

            Bitmap bitmap = new Bitmap(label.Width, label.Height);

            label.SetMinMax();
            int val = label.Max - label.Min + 1;
            int c   = (byte.MaxValue + 1) / val;

            if (c == 0)
            {
                c = 16;
            }

            logWriter.Write("分割数  =" + val);
            logWriter.Write("色の変化量=" + c);

            {
                BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                byte[]     buf  = new byte[bitmap.Width * bitmap.Height * 4];
                Marshal.Copy(data.Scan0, buf, 0, buf.Length);

                for (int y = 0; y < bitmap.Height; y++)
                {
                    for (int x = 0; x < bitmap.Width; x++)
                    {
                        int index = y * bitmap.Width * 4 + x * 4;
                        int color = label[y, x] * c;
                        buf[index + 0] = buf[index + 1] = buf[index + 2] = (byte)color;
                        buf[index + 3] = byte.MaxValue;
                    }
                }

                Marshal.Copy(buf, 0, data.Scan0, buf.Length);
                bitmap.UnlockBits(data);
            }

            logWriter.Write("ラベルデータの画像作成が完了しました");

            return(bitmap);
        }
Beispiel #5
0
        /// <summary>
        /// StartButton_Clickから呼び出される関数です
        /// </summary>
        private async Task ProcessAsync()
        {
            logWriter.Write("処理を開始します");
            CancellationToken token = tokenSource.Token;

            Bitmap originalImage = await Task.Run(() => { return(new LoadImage(logWriter).Load(fileTextBox.Text)); });

            token.ThrowIfCancellationRequested();

            if (originalImage == null)
            {
                return;
            }

            new ImageWindow("元画像", originalImage, logWriter);

            Bitmap kmeansImage = await new K_means(8, logWriter).GetImageAsync(originalImage, tokenSource);

            token.ThrowIfCancellationRequested();

            new ImageWindow("減色画像(k-means)", kmeansImage, logWriter);

            Bitmap medianImage = await new MedianFilter(logWriter).GetImageAsync(kmeansImage);

            token.ThrowIfCancellationRequested();

            new ImageWindow("メディアンフィルタ", medianImage, logWriter);
            token.ThrowIfCancellationRequested();

            LabelStructure label = await new Labeling(logWriter).GetLabelTableAsync(medianImage, tokenSource);

            token.ThrowIfCancellationRequested();

            Bitmap labelImage = await new Labeling(logWriter).GetLabelImageAsync(label);

            new ImageWindow("ラベリング画像", labelImage, logWriter);

            LabelStructure depth = await new Guess01(logWriter).GetDepthAsync(label, tokenSource);

            token.ThrowIfCancellationRequested();

            Bitmap depthImage = await new Labeling(logWriter).GetLabelImageAsync(depth);

            new ImageWindow("深さ情報", depthImage, logWriter);

            SaveImage(originalImage, depth);
            logWriter.Write("処理が完了しました");
        }
Beispiel #6
0
        /// <summary>深さ情報を持った画像のバイナリデータを保存する</summary>
        /// <param name="image">保存したい画像</param>
        /// <param name="depth">画像の深さデータ</param>
        /// <param name="path">保存したい場所</param>
        public void SaveBinary(Bitmap image, LabelStructure depth, string path)
        {
            /*
             * バイナリデータの保存形式
             * 0_3byte  画像の横幅(int)
             * 4_7byte  画像の縦幅(int)
             * 8_byte   色・深さの情報
             * 8n   byte  赤色情報(byte)
             * 8n+1 byte  緑色情報(byte)
             * 8n+2 byte  青色情報(byte)
             * 8n+3 byte  アルファ情報(byte)
             * 8n+4_8n+7byte  深さ情報(int)
             * 以下画像の大きさだけループ
             */

            logWriter.Write("三次元画像を保存します");

            try
            {
                using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(path)))
                {
                    bw.Write(image.Width);
                    bw.Write(image.Height);
                    for (int y = 0; y < image.Height; y++)
                    {
                        for (int x = 0; x < image.Width; x++)
                        {
                            Color c = image.GetPixel(x, y);
                            bw.Write(c.R);
                            bw.Write(c.G);
                            bw.Write(c.B);
                            bw.Write(c.A);
                            bw.Write(depth[y, x]);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logWriter.WriteError("三次元画像の保存に失敗しました");
                logWriter.WriteError(ex.ToString());
                return;
            }

            logWriter.Write("三次元画像を保存しました");
            logWriter.Write("path=" + path);
        }
Beispiel #7
0
        /// <summary>深さごとに画像を保存する</summary>
        /// <param name="image">保存したい画像</param>
        /// <param name="depth">画像の深さデータ</param>
        /// <param name="path">保存したい場所</param>
        public void SaveChip(Bitmap image, LabelStructure depth, string path)
        {
            logWriter.Write("画像を保存します");

            try
            {
                for (int i = depth.Min; i <= depth.Max; i++)
                {
                    Bitmap     bitmap = new Bitmap(image);
                    BitmapData data   = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                    byte[]     buf    = new byte[bitmap.Width * bitmap.Height * 4];
                    Marshal.Copy(data.Scan0, buf, 0, buf.Length);

                    for (int y = 0; y < bitmap.Height; y++)
                    {
                        for (int x = 0; x < bitmap.Width; x++)
                        {
                            if (depth[y, x] != i)
                            {
                                int index = y * bitmap.Width * 4 + x * 4;
                                buf[index + 0] = 0;
                                buf[index + 1] = 0;
                                buf[index + 2] = 0;
                                buf[index + 3] = 0;
                            }
                        }
                    }

                    Marshal.Copy(buf, 0, data.Scan0, buf.Length);
                    bitmap.UnlockBits(data);

                    string name = path + "_" + i.ToString() + ".png";
                    bitmap.Save(name);
                    logWriter.Write("path=" + name);
                }
            }
            catch (Exception ex)
            {
                logWriter.WriteError("三次元画像の保存に失敗しました");
                logWriter.WriteError(ex.ToString());
                return;
            }

            logWriter.Write("画像を保存しました");
        }
Beispiel #8
0
        /// <summary>画像の深度を推測する</summary>
        /// <param name="label">ラベリング結果</param>
        /// <param name="token">キャンセルトークン</param>
        /// <returns>深度ラベル</returns>
        private LabelStructure GetDepth(LabelStructure label, CancellationTokenSource token)
        {
            logWriter.Write("深さ推測を行います");

            if (label == null)
            {
                logWriter.WriteError("ラベルデータがありません");
                logWriter.WriteError("深さ推測を中止します");
                return(null);
            }

            int[][] link = new RingDetection(logWriter).GetInclusionLink(label, token);
            if (token.IsCancellationRequested)
            {
                return(null);
            }

            int[] depthTable = new int[link.Length];

            for (int i = 0; i < link.Length; i++)
            {
                for (int j = 0; j < link[i].Length; j++)
                {
                    depthTable[link[i][j]]++;
                }
            }

            LabelStructure depthGrid = new LabelStructure(label.Width, label.Height);

            for (int y = 0; y < label.Height; y++)
            {
                for (int x = 0; x < label.Width; x++)
                {
                    int num = label[y, x];
                    depthGrid[y, x] = depthTable[num];
                }
            }

            logWriter.Write("深さ推測を行いました");
            return(depthGrid);
        }
Beispiel #9
0
        /// <summary>画像の明るさを得る</summary>
        /// <param name="bmp">画像</param>
        /// <returns>光度ラベル</returns>
        public LabelStructure GetBrightness(Bitmap bmp)
        {
            LabelStructure label = new LabelStructure(bmp.Width, bmp.Height);

            BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            byte[] buf = new byte[bmp.Width * bmp.Height * 4];
            Marshal.Copy(data.Scan0, buf, 0, buf.Length);
            bmp.UnlockBits(data);

            for (int i = 0; i < buf.Length; i += 4)
            {
                HSV hsv = HSV.FromRGB(buf[i + 0], buf[i + 1], buf[i + 2]);
                int x   = i / 4 % bmp.Width;
                int y   = i / 4 / bmp.Width;

                label[y, x] = (int)(hsv.V * 255);
            }

            return(label);
        }
Beispiel #10
0
        /// <summary>画像を保存します</summary>
        /// <param name="image">画像</param>
        /// <param name="depth">深さ</param>
        private void SaveImage(Bitmap image, LabelStructure depth)
        {
            DialogResult com = MessageBox.Show("3次元画像を保存しますか?", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (com == DialogResult.Yes)
            {
                SaveFileDialog saveDialog = new SaveFileDialog();
                saveDialog.Filter     = "3次元画像|*.rgbad;*.txt";
                saveDialog.Title      = "保存";
                saveDialog.DefaultExt = "rgbad";
                if (saveDialog.ShowDialog() == DialogResult.OK)
                {
                    string    path      = Path.GetDirectoryName(saveDialog.FileName) + "\\" + Path.GetFileNameWithoutExtension(saveDialog.FileName);
                    SaveImage saveImage = new SaveImage(logWriter);
                    saveImage.Save(image, depth, path + ".txt");
                    saveImage.SaveBinary(image, depth, path + ".rgbad");
                    depth.SetMinMax();
                    saveImage.SaveChip(image, depth, path);
                }
            }
        }
Beispiel #11
0
        /// <summary>画像の深度を推測する</summary>
        /// <param name="label">ラベリング結果</param>
        /// <returns>深度ラベル</returns>
        public LabelStructure GetDepth(LabelStructure label)
        {
            logWriter.Write("深さ推測を行います");

            if (label == null)
            {
                logWriter.WriteError("ラベルデータがありません");
                logWriter.WriteError("深さ推測を中止します");
                return(null);
            }

            int[][] link = new RingDetection(logWriter).GetInclusionLink(label);

            int[] depthTable = new int[link.Length];

            for (int i = 0; i < link.Length; i++)
            {
                for (int j = 0; j < link[i].Length; j++)
                {
                    depthTable[link[i][j]]++;
                }
            }

            LabelStructure depthGrid = new LabelStructure(new int[label.Height, label.Width]);

            for (int y = 0; y < label.Height; y++)
            {
                for (int x = 0; x < label.Width; x++)
                {
                    int num = label[y, x];
                    depthGrid[y, x] = depthTable[num];
                }
            }

            logWriter.Write("深さ推測を行いました");
            return(depthGrid);
        }
Beispiel #12
0
 /// <summary>画像の深度を推測する(非同期)</summary>
 /// <param name="label">ラベリング結果</param>
 /// <param name="token">キャンセルトークン</param>
 /// <returns>深度ラベル</returns>
 public async Task <LabelStructure> GetDepthAsync(LabelStructure label, CancellationTokenSource token)
 {
     return(await Task.Run(() => GetDepth(label, token)));
 }
Beispiel #13
0
        //遅い・不正確
        /// <summary>特定のラベルの包含関係を調べる</summary>
        /// <param name="label">ラベリングデータ</param>
        /// <param name="n">ラベル番号</param>
        /// <returns>包含関係</returns>
        private int[] GetInclusionNumber(LabelStructure label, int n)
        {
            int[] dx = new int[] { -1, 0, 1, -1 };
            int[] dy = new int[] { -1, -1, -1, 0 };

            Dictionary <int, bool> table = new Dictionary <int, bool>();

            for (int y = 0; y < label.Height; y++)
            {
                for (int x = 0; x < label.Width; x++)
                {
                    if (!table.ContainsKey(label[y, x]))
                    {
                        table[label[y, x]] = false;
                    }

                    if (x - 1 < 0 || label.Width <= x + 1 || y - 1 < 0 || label.Height <= y + 1)
                    {
                        table[label[y, x]] = true;

                        for (int i = 0; i < 4; i++)
                        {
                            if (0 <= x + dx[i] && x + dx[i] < label.Width && 0 <= y + dy[i])
                            {
                                if (label[y + dy[i], x + dx[i]] != n)
                                {
                                    table[label[y + dy[i], x + dx[i]]] = true;
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < 4; i++)
                        {
                            if (0 <= x + dx[i] && x + dx[i] < label.Width && 0 <= y + dy[i])
                            {
                                if (label[y + dy[i], x + dx[i]] != n)
                                {
                                    int l = label[y + dy[i], x + dx[i]];
                                    if (table[l])
                                    {
                                        table[label[y, x]] = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            HashSet <int> inclusion = new HashSet <int>();

            for (int y = 0; y < label.Height; y++)
            {
                for (int x = 0; x < label.Width; x++)
                {
                    if (label[y, x] != n && !table[label[y, x]])
                    {
                        inclusion.Add(label[y, x]);
                    }
                }
            }

            return(inclusion.ToArray());
        }
Beispiel #14
0
        //早い・不正確
        /// <summary>特定のラベルの包含関係を調べる</summary>
        /// <param name="label">ラベリングデータ</param>
        /// <param name="n">ラベル番号</param>
        /// <returns>包含関係</returns>
        private int[] GetInclusionNumber2(LabelStructure label, int n)
        {
            Dictionary <int, bool> table = new Dictionary <int, bool>();

            for (int i = label.Min; i <= label.Max; i++)
            {
                table[i] = false;
            }

            for (int x = 0; x < label.Width; x++)
            {
                if (label[0, x] != n)
                {
                    table[label[0, x]] = true;
                }
                if (label[label.Height - 1, x] != n)
                {
                    table[label[label.Height - 1, x]] = true;
                }
            }
            for (int y = 0; y < label.Height; y++)
            {
                if (label[y, 0] != n)
                {
                    table[label[y, 0]] = true;
                }
                if (label[y, label.Width - 1] != n)
                {
                    table[label[y, label.Width - 1]] = true;
                }
            }

            for (int y = 1; y < label.Height - 1; y++)
            {
                for (int x = 1; x < label.Width - 1; x++)
                {
                    if (label[y, x] != n && !table[label[y, x]])
                    {
                        foreach (var d in Config.Direction)
                        {
                            int num = label[y + d.Y, x + d.X];

                            if (table[num])
                            {
                                table[label[y, x]] = true;
                                break;
                            }
                        }
                    }
                }
            }

            List <int> list = new List <int>();

            table[n] = true;

            foreach (var val in table)
            {
                if (!val.Value)
                {
                    list.Add(val.Key);
                }
            }

            return(list.ToArray());
        }
Beispiel #15
0
        //遅い・正確
        /// <summary>特定のラベルの包含関係を調べる</summary>
        /// <param name="label">ラベリングデータ</param>
        /// <param name="n">ラベル番号</param>
        /// <returns>包含関係</returns>
        private int[] GetInclusionNumber3(LabelStructure label, int n)
        {
            int[] table = new int[label.Max - label.Min + 1];
            for (int i = 0; i < table.Length; i++)
            {
                table[i] = i;
            }

            for (int y = 0; y < label.Height; y++)
            {
                for (int x = 0; x < label.Width; x++)
                {
                    if (label[y, x] != n)
                    {
                        int min = int.MaxValue;

                        foreach (var d in Config.Direction)
                        {
                            if (0 <= x + d.X && x + d.X < label.Width && 0 <= y + d.Y && y + d.Y < label.Height)
                            {
                                if (label[y + d.Y, x + d.X] != n)
                                {
                                    min = Math.Min(min, table[label[y + d.Y, x + d.X]]);
                                }
                            }
                        }

                        if (table[label[y, x]] > min)
                        {
                            for (int i = 0; i < table.Length; i++)
                            {
                                if (table[i] == table[label[y, x]])
                                {
                                    table[i] = min;
                                }
                            }
                            for (int i = 0; i < table.Length; i++)
                            {
                                while (table[i] != table[table[i]])
                                {
                                    table[i] = table[table[i]];
                                }
                            }
                        }
                    }
                }
            }

            for (int x = 0; x < label.Width; x++)
            {
                table[label[0, x]] = 0;
                table[label[label.Height - 1, x]] = 0;
            }
            for (int y = 0; y < label.Height; y++)
            {
                table[label[y, 0]] = 0;
                table[label[y, label.Width - 1]] = 0;
            }
            for (int i = 0; i < table.Length; i++)
            {
                while (table[i] != table[table[i]])
                {
                    table[i] = table[table[i]];
                }
            }

            List <int> list = new List <int>();

            for (int i = 0; i < table.Length; i++)
            {
                if (table[i] != 0 && i != n)
                {
                    list.Add(i);
                }
            }

            return(list.ToArray());
        }
Beispiel #16
0
 /// <summary>ラベル情報を視覚化する(非同期)</summary>
 /// <param name="label">視覚化したいラベルデータ</param>
 /// <returns>視覚化された画像<see cref="Bitmap"/></returns>
 public async Task <Bitmap> GetLabelImageAsync(LabelStructure label)
 {
     return(await Task.Run(() => GetLabelImage(label)));
 }
Beispiel #17
0
        /// <summary>画像からラベルを作成する</summary>
        /// <param name="bmp">ラベルを作成したい画像</param>
        /// <param name="token">中断用構造体</param>
        /// <returns>ラベル情報<see cref="LabelStructure" /></returns>
        private LabelStructure GetLabelTable(Bitmap bmp, CancellationTokenSource token)
        {
            logWriter.Write("ラベリング処理を行います");

            if (bmp == null)
            {
                logWriter.WriteError("画像が存在しません");
                logWriter.WriteError("ラベリング処理を中止します");
                return(null);
            }

            LabelStructure label = new LabelStructure(bmp.Width, bmp.Height);

            #region カラー配列の作成
            BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            byte[]     buf  = new byte[bmp.Width * bmp.Height * 4];
            Marshal.Copy(data.Scan0, buf, 0, buf.Length);
            bmp.UnlockBits(data);
            #endregion

            Func <int, int, int> ToIndex = (x, y) => { return(y * bmp.Width * 4 + x * 4); };

            #region 番号振り分け
            Func <int, int, int> SearchLabel = (x, y) =>
            {
                int max = 0;

                int index1 = ToIndex(x, y);

                foreach (var d in Config.Direction)
                {
                    int index2 = ToIndex(x + d.X, y + d.Y);
                    if (0 <= x + d.X && x + d.X < label.Width && 0 <= y + d.Y && y + d.Y < label.Height)
                    {
                        if (buf[index1 + 0] == buf[index2 + 0] && buf[index1 + 1] == buf[index2 + 1] && buf[index1 + 2] == buf[index2 + 2])
                        {
                            max = Math.Max(max, label[y + d.Y, x + d.X]);
                        }
                    }
                }

                return(max);
            };

            int count = 0;
            for (int y = 0; y < label.Height; y++)
            {
                for (int x = 0; x < label.Width; x++)
                {
                    int num = SearchLabel(x, y);
                    if (num == 0)
                    {
                        label[y, x] = count + 1;
                        count++;
                    }
                    else
                    {
                        label[y, x] = num;
                    }
                }
            }
            #endregion

            #region 番号テーブルの作成
            int[] table = new int[count + 1];
            for (int i = 0; i < table.Length; i++)
            {
                table[i] = i;
            }

            Func <int, int, int> SearchTable = (x, y) =>
            {
                int max = 0;

                int index1 = ToIndex(x, y);

                foreach (var d in Config.Direction)
                {
                    int index2 = ToIndex(x + d.X, y + d.Y);
                    if (0 <= x + d.X && x + d.X < label.Width && 0 <= y + d.Y && y + d.Y < label.Height)
                    {
                        if (buf[index1 + 0] == buf[index2 + 0] && buf[index1 + 1] == buf[index2 + 1] && buf[index1 + 2] == buf[index2 + 2])
                        {
                            max = Math.Max(max, table[label[y + d.Y, x + d.X]]);
                        }
                    }
                }

                return(max);
            };

            for (int y = 0; y < label.Height; y++)
            {
                for (int x = 0; x < label.Width; x++)
                {
                    int num = SearchTable(x, y);
                    if (num != 0)
                    {
                        if (num > table[label[y, x]])
                        {
                            for (int i = 0; i < table.Length; i++)
                            {
                                if (table[i] == num)
                                {
                                    table[i] = label[y, x];
                                }
                            }
                            for (int i = 0; i < table.Length; i++)
                            {
                                while (table[i] != table[table[i]])
                                {
                                    table[i] = table[table[i]];
                                }
                            }
                        }
                    }
                }
            }
            #endregion

            #region 番号の最適化
            int newCount = 0;
            for (int i = 0; i < table.Length; i++)
            {
                if (newCount < table[i])
                {
                    int n = table[i];
                    for (int j = 0; j < table.Length; j++)
                    {
                        if (table[j] == n)
                        {
                            table[j] = newCount;
                        }
                    }
                    newCount++;
                }
            }

            for (int y = 0; y < label.Height; y++)
            {
                for (int x = 0; x < label.Width; x++)
                {
                    label[y, x] = table[label[y, x]];
                }
            }
            #endregion

            logWriter.Write("ラベリング処理が完了しました");
            return(label);
        }