diff --git a/Tongue extraction_cropresizemethod/Tongue extraction/ColorExtractor.cs b/Tongue extraction_cropresizemethod/Tongue extraction/ColorExtractor.cs index 813ef73..071abc5 100644 --- a/Tongue extraction_cropresizemethod/Tongue extraction/ColorExtractor.cs +++ b/Tongue extraction_cropresizemethod/Tongue extraction/ColorExtractor.cs @@ -8,11 +8,11 @@ namespace Tongue_extraction { - class ColorExtractor + public partial class ColorExtractor { + // Config const int RADIUS_COLORAREA = 10; public static Bitmap bitmap; - float[] a = new float[17]; float[] b = new float[17]; float[] c = new float[17]; @@ -28,62 +28,11 @@ double[] m_RforLab = new double[24]; public static bool m_bCalib; public static OpenCvSharp.Point pt = new OpenCvSharp.Point();//キャリブレーション用のポイント入れ - public static Mat m_PointedFrame; //ポイントされたMat - public static int click = 0; //クリック回数 - OpenCvSharp.Point P1 = new OpenCvSharp.Point(); - OpenCvSharp.Point P2 = new OpenCvSharp.Point(); + public enum FivePointMethod {Method1, Method2, Method3}; - public void ColorExtract() + public List Get5points(Mat mat_finalMask, FivePointMethod method) { - // GetImage() - var path_oriImg = @"data_lab\d\Shot0001.bmp"; - var path_calibCsv = @"data_lab\d\Calib.csv"; - var path_colorMatrixXYZ = "xyz.txt"; - using (Mat mat_oriImg = Cv2.ImRead(path_oriImg, ImreadModes.Color)) - { - // Process_DeepTIAS() - var path_mask = @"data_lab\d\Shot0001_mask.bmp"; - Mat mat_finalMask = Cv2.ImRead(path_mask, ImreadModes.Grayscale); - Cv2.Threshold(mat_finalMask, mat_finalMask, 128, 255, ThresholdTypes.Binary); - - // マスクされた舌領域画像の作成 - Mat mat_maskedImg = new Mat(); - mat_oriImg.CopyTo(mat_maskedImg, mat_finalMask); - - // 5点クリック法(2010石川) - List list_5points = Get5points(mat_finalMask); - - // 8領域の取得 - List list_8area = Get8area(list_5points); - Show8area(mat_oriImg.Clone(), list_8area); - - /* - // 色抽出 - List list_8Bgr = Get8colors(mat_maskedImg, list_8area); - - // 色変換(RGB->XYZ->Lab) - List list_8Lab = Calc8Lab(list_8Bgr, path_calibCsv, path_colorMatrixXYZ); - - // 色の表示 - Show8colors(list_8Bgr, list_8Lab); - - // 保存 - // Write8colors(list_8Bgr, list_8Lab); - */ - - - // 廃棄 - mat_finalMask.Dispose(); - mat_maskedImg.Dispose(); - GC.Collect(); - } - } - - private List Get5points(Mat mat_finalMask) - { - List li_dst; - // 表示用 var mat_dst = mat_finalMask.Clone(); Cv2.CvtColor(mat_dst, mat_dst, ColorConversionCodes.GRAY2BGR); @@ -103,160 +52,225 @@ list_Y.Add(y); } - /// method1 - // 端っこを探索(ラスタ左上から) - var p_top = mat_nonZeroCoordinates.At(list_Y.IndexOf(list_Y.Min())); - var p_bottom = mat_nonZeroCoordinates.At(list_Y.IndexOf(list_Y.Max())); - var p_left = mat_nonZeroCoordinates.At(list_X.IndexOf(list_X.Min())); - var p_right = mat_nonZeroCoordinates.At(list_X.IndexOf(list_X.Max())); - - // 舌尖領域を示すy座標を取得(割合を今回は決め打ち) - var y_apex = (int)(p_top.Y + ((p_bottom.Y - p_top.Y) * 0.8)); - var p_apex_left = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_apex).Min()); - var p_apex_right = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_apex).Max()); - - // 表示してみる - //Cv2.Circle(mat_dst, p_top, 20, new Scalar(255, 255, 0), -1); - Cv2.Circle(mat_dst, p_bottom, 20, new Scalar(255, 255, 0), -1); - //Cv2.Circle(mat_dst, p_left, 20, new Scalar(255, 255, 0), -1); - //Cv2.Circle(mat_dst, p_right, 20, new Scalar(255, 255, 0), -1); - //Cv2.Circle(mat_dst, p_apex_left, 20, new Scalar(255, 255, 0), -1); - //Cv2.Circle(mat_dst, p_apex_right, 20, new Scalar(255, 255, 0), -1); - - /// method2 - // 重心(CoG)計算 - var moments = Cv2.Moments(mat_finalMask, true); - var moment_x = moments.M10 / moments.M00; - var moment_y = moments.M01 / moments.M00; - - // 輪郭座標 - OpenCvSharp.Point[][] contours; - HierarchyIndex[] hierarchy; - Cv2.FindContours(mat_finalMask, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple); - - // 重心-輪郭の距離 - double maxDistance_lefttop = 0.0; - double maxDistance_righttop = 0.0; - double maxDistance_bottom = 0.0; - var p_left_2 = new OpenCvSharp.Point(); - var p_right_2 = new OpenCvSharp.Point(); - var p_bottom_2 = new OpenCvSharp.Point(); - // 距離が最も遠いものを採択 - for (int i = 0; i < contours[0].Length; i++) + if(method == FivePointMethod.Method1) { - // 重心より上側 - if (contours[0][i].Y < moment_y) - { - // 重心より上側左側 - if (contours[0][i].X < moment_x) - { - var distance = contours[0][i].DistanceTo(new OpenCvSharp.Point(moment_x, moment_y)); - if (distance > maxDistance_lefttop) - { - maxDistance_lefttop = distance; - p_left_2 = contours[0][i]; - } + /// method1 + // 端っこを探索(ラスタ左上から) + var p_top = mat_nonZeroCoordinates.At(list_Y.IndexOf(list_Y.Min())); + var p_bottom = mat_nonZeroCoordinates.At(list_Y.IndexOf(list_Y.Max())); + var p_left = mat_nonZeroCoordinates.At(list_X.IndexOf(list_X.Min())); + var p_right = mat_nonZeroCoordinates.At(list_X.IndexOf(list_X.Max())); - } - // 重心より上側右側 - if (contours[0][i].X >= moment_x) + // 舌尖領域を示すy座標を取得(割合を今回は決め打ち) + var y_apex = (int)(p_top.Y + ((p_bottom.Y - p_top.Y) * 0.8)); + var p_apex_left = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_apex).Min()); + var p_apex_right = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_apex).Max()); + + // 表示してみる + //Cv2.Circle(mat_dst, p_top, 20, new Scalar(255, 255, 0), -1); + //Cv2.Circle(mat_dst, p_bottom, 20, new Scalar(255, 255, 0), -1); + //Cv2.Circle(mat_dst, p_left, 20, new Scalar(255, 255, 0), -1); + //Cv2.Circle(mat_dst, p_right, 20, new Scalar(255, 255, 0), -1); + //Cv2.Circle(mat_dst, p_apex_left, 20, new Scalar(255, 255, 0), -1); + //Cv2.Circle(mat_dst, p_apex_right, 20, new Scalar(255, 255, 0), -1); + + mat_dst.Dispose(); + mat_nonZeroCoordinates.Dispose(); + GC.Collect(); + + var li_dst = new List { p_left, p_apex_left, p_bottom, p_apex_right, p_right }; + return li_dst; + } + else if (method == FivePointMethod.Method2) + { + /// method2 + // 重心(CoG)計算 + var moments = Cv2.Moments(mat_finalMask, true); + var moment_x = moments.M10 / moments.M00; + var moment_y = moments.M01 / moments.M00; + + // 輪郭座標 + OpenCvSharp.Point[][] contours; + HierarchyIndex[] hierarchy; + Cv2.FindContours(mat_finalMask, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple); + + // 重心-輪郭の距離 + double maxDistance_lefttop = 0.0; + double maxDistance_righttop = 0.0; + var p_left_2 = new OpenCvSharp.Point(); + var p_right_2 = new OpenCvSharp.Point(); + // 距離が最も遠いものを採択 + for (int i = 0; i < contours[0].Length; i++) + { + // 重心より上側 + if (contours[0][i].Y < moment_y) { - var distance = contours[0][i].DistanceTo(new OpenCvSharp.Point(moment_x, moment_y)); - if (distance > maxDistance_righttop) + // 重心より上側左側 + if (contours[0][i].X < moment_x) { - maxDistance_righttop = distance; - p_right_2 = contours[0][i]; + var distance = contours[0][i].DistanceTo(new OpenCvSharp.Point(moment_x, moment_y)); + if (distance > maxDistance_lefttop) + { + maxDistance_lefttop = distance; + p_left_2 = contours[0][i]; + } + + } + // 重心より上側右側 + if (contours[0][i].X >= moment_x) + { + var distance = contours[0][i].DistanceTo(new OpenCvSharp.Point(moment_x, moment_y)); + if (distance > maxDistance_righttop) + { + maxDistance_righttop = distance; + p_right_2 = contours[0][i]; + } } } } - else + // 舌尖領域を示すy座標を取得(割合を今回は決め打ち) + var p_bottom = mat_nonZeroCoordinates.At(list_Y.IndexOf(list_Y.Max())); + var y_top_avg_ = (p_left_2.Y + p_right_2.Y) / 2.0; + var y_apex_2 = (int)(y_top_avg_ + ((p_bottom.Y - y_top_avg_) * 0.57)); + var p_apex_left_2 = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_apex_2).Min()); + var p_apex_right_2 = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_apex_2).Max()); + + // 表示 + //Cv2.Circle(mat_dst, p_left_2, 20, new Scalar(255, 0, 0), -1); + //Cv2.Circle(mat_dst, p_right_2, 20, new Scalar(255, 0, 0), -1); + //Cv2.Circle(mat_dst, p_bottom_2, 20, new Scalar(255, 0, 0), -1); + //Cv2.Circle(mat_dst, p_apex_left_2, 20, new Scalar(255, 0, 0), -1); + //Cv2.Circle(mat_dst, p_apex_right_2, 20, new Scalar(255, 0, 0), -1); + //Cv2.Circle(mat_dst, new OpenCvSharp.Point(moment_x, moment_y), 10, new Scalar(200, 60, 200), -1); //重心 + //Cv2.DrawContours(mat_dst, contours, 0, new Scalar(0, 255, 255), 4); // 輪郭 + mat_dst.Dispose(); + mat_nonZeroCoordinates.Dispose(); + GC.Collect(); + + var li_dst = new List { p_left_2, p_apex_left_2, p_bottom, p_apex_right_2, p_right_2 }; + return li_dst; + } + else if (method == FivePointMethod.Method3) + { + /// method3 + // 重心(CoG)計算 + var moments = Cv2.Moments(mat_finalMask, true); + var moment_x = moments.M10 / moments.M00; + var moment_y = moments.M01 / moments.M00; + + // 輪郭座標 + OpenCvSharp.Point[][] contours; + HierarchyIndex[] hierarchy; + Cv2.FindContours(mat_finalMask, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple); + + // 重心-輪郭の距離 + double maxDistance_lefttop = 0.0; + double maxDistance_righttop = 0.0; + var p_left_3 = new OpenCvSharp.Point(); + var p_right_3 = new OpenCvSharp.Point(); + // 距離が最も遠いものを採択 + for (int i = 0; i < contours[0].Length; i++) { - var distance = contours[0][i].DistanceTo(new OpenCvSharp.Point(moment_x, moment_y)); - if (distance > maxDistance_bottom) + // 重心より上側 + if (contours[0][i].Y < moment_y) { - maxDistance_bottom = distance; - p_bottom_2 = contours[0][i]; + // 重心より上側左側 + if (contours[0][i].X < moment_x) + { + var distance = contours[0][i].DistanceTo(new OpenCvSharp.Point(moment_x, moment_y)); + if (distance > maxDistance_lefttop) + { + maxDistance_lefttop = distance; + p_left_3 = contours[0][i]; + } + + } + // 重心より上側右側 + if (contours[0][i].X >= moment_x) + { + var distance = contours[0][i].DistanceTo(new OpenCvSharp.Point(moment_x, moment_y)); + if (distance > maxDistance_righttop) + { + maxDistance_righttop = distance; + p_right_3 = contours[0][i]; + } + } } } - } - // 舌尖領域を示すy座標を取得(割合を今回は決め打ち) - var y_top_avg_ = (p_left_2.Y + p_right_2.Y) / 2.0; - var y_apex_2 = (int)(y_top_avg_ + ((p_bottom_2.Y - y_top_avg_) * 0.53)); - var p_apex_left_2 = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_apex_2).Min()); - var p_apex_right_2 = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_apex_2).Max()); + // 重心とtopの中点を算出する + var p_top = mat_nonZeroCoordinates.At(list_Y.IndexOf(list_Y.Min())); + var y_topToCoG = (int)(moment_y + p_top.Y) / 2; + var p_topToCoG_left = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_topToCoG).Min()); + var p_topToCoG_right = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_topToCoG).Max()); + var p_topToCoG_center = new OpenCvSharp.Point((int)((p_topToCoG_left.X + p_topToCoG_right.X) / 2), y_topToCoG); + // 重心とbottomの中点を算出する + var p_bottom = mat_nonZeroCoordinates.At(list_Y.IndexOf(list_Y.Max())); + var y_bottomToCoG = (int)(moment_y + p_bottom.Y) / 2; + var p_bottomToCoG_left = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_bottomToCoG).Min()); + var p_bottomToCoG_right = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_bottomToCoG).Max()); + var p_bottomToCoG_center = new OpenCvSharp.Point((int)((p_bottomToCoG_left.X + p_bottomToCoG_right.X) / 2), y_bottomToCoG); - // 表示 - //Cv2.Circle(mat_dst, p_left_2, 20, new Scalar(255, 0, 0), -1); - //Cv2.Circle(mat_dst, p_right_2, 20, new Scalar(255, 0, 0), -1); - Cv2.Circle(mat_dst, p_bottom_2, 20, new Scalar(255, 0, 0), -1); - //Cv2.Circle(mat_dst, p_apex_left_2, 20, new Scalar(255, 0, 0), -1); - //Cv2.Circle(mat_dst, p_apex_right_2, 20, new Scalar(255, 0, 0), -1); - Cv2.Circle(mat_dst, new OpenCvSharp.Point(moment_x, moment_y), 10, new Scalar(200, 60, 200), -1); //重心 - //Cv2.DrawContours(mat_dst, contours, 0, new Scalar(0, 255, 255), 4); // 輪郭 - - /// method3 - // 重心とtopの中点を算出する - var y_topToCoG = (int)(moment_y + p_top.Y) / 2; - var p_topToCoG_left = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_topToCoG).Min()); - var p_topToCoG_right = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_topToCoG).Max()); - var p_topToCoG_center = new OpenCvSharp.Point((int)((p_topToCoG_left.X + p_topToCoG_right.X) / 2), y_topToCoG); - // 重心とbottomの中点を算出する - var y_bottomToCoG = (int)(moment_y + p_bottom.Y) / 2; - var p_bottomToCoG_left = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_bottomToCoG).Min()); - var p_bottomToCoG_right = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_bottomToCoG).Max()); - var p_bottomToCoG_center = new OpenCvSharp.Point((int)((p_bottomToCoG_left.X + p_bottomToCoG_right.X) / 2), y_bottomToCoG); - // 直線フィッティング - var line = Cv2.FitLine(new OpenCvSharp.Point[2] { p_topToCoG_center, p_bottomToCoG_center }, DistanceTypes.L2, 0, 0.01, 0.0); - var lefty = (int)((-line.X1 * line.Vy / line.Vx) + line.Y1); - var righty = (int)(((mat_finalMask.Cols - line.X1) * line.Vy / line.Vx) + line.Y1); - // 直線上の輪郭点 - var mat_centerline = new Mat(mat_finalMask.Size(), MatType.CV_8UC1, 0); - var mat_contour = new Mat(mat_finalMask.Size(), MatType.CV_8UC1, 0); - var mat_and = new Mat(mat_finalMask.Size(), MatType.CV_8UC1, 0); - Cv2.Line(mat_centerline, new OpenCvSharp.Point(0, lefty), new OpenCvSharp.Point(mat_finalMask.Cols - 1, righty), 3); - Cv2.DrawContours(mat_contour, contours, 0, 3); - Cv2.BitwiseAnd(mat_centerline, mat_contour, mat_and); - Cv2.FindNonZero(mat_and, mat_and); - var bottom_y_3 = 0; - var bottom_x_3 = 0; - for (int i = 0; i < mat_and.Total(); i++) - { - var x = mat_and.At(i).X; - var y = mat_and.At(i).Y; - if (bottom_y_3 < y) + // 直線フィッティング + var line = Cv2.FitLine(new OpenCvSharp.Point[2] { p_topToCoG_center, p_bottomToCoG_center }, DistanceTypes.L2, 0, 0.01, 0.0); + var lefty = (int)((-line.X1 * line.Vy / line.Vx) + line.Y1); + var righty = (int)(((mat_finalMask.Cols - line.X1) * line.Vy / line.Vx) + line.Y1); + // 直線上の輪郭点 + var mat_centerline = new Mat(mat_finalMask.Size(), MatType.CV_8UC1, 0); + var mat_contour = new Mat(mat_finalMask.Size(), MatType.CV_8UC1, 0); + var mat_and = new Mat(mat_finalMask.Size(), MatType.CV_8UC1, 0); + Cv2.Line(mat_centerline, new OpenCvSharp.Point(0, lefty), new OpenCvSharp.Point(mat_finalMask.Cols - 1, righty), 3); + Cv2.DrawContours(mat_contour, contours, 0, 3); + Cv2.BitwiseAnd(mat_centerline, mat_contour, mat_and); + Cv2.FindNonZero(mat_and, mat_and); + var bottom_y_3 = 0; + var bottom_x_3 = 0; + for (int i = 0; i < mat_and.Total(); i++) { - bottom_y_3 = y; - bottom_x_3 = x; + var x = mat_and.At(i).X; + var y = mat_and.At(i).Y; + if (bottom_y_3 < y) + { + bottom_y_3 = y; + bottom_x_3 = x; + } } + var p_bottom_3 = new OpenCvSharp.Point(bottom_x_3, bottom_y_3); + + // 舌尖領域を示すy座標を取得(割合を今回は決め打ち) + var y_top_avg_ = (p_left_3.Y + p_right_3.Y) / 2.0; + var y_apex_3 = (int)(y_top_avg_ + ((p_bottom_3.Y - y_top_avg_) * 0.57)); + var p_apex_left_3 = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_apex_3).Min()); + var p_apex_right_3 = mat_nonZeroCoordinates.At(IndexOfAll(list_Y, y_apex_3).Max()); + + //Cv2.Circle(mat_dst, p_topToCoG_left, 20, new Scalar(0, 100, 255), -1); + //Cv2.Circle(mat_dst, p_topToCoG_right, 20, new Scalar(0, 100, 255), -1); + //Cv2.Circle(mat_dst, p_topToCoG_center, 20, new Scalar(0, 0, 255), -1); + //Cv2.Circle(mat_dst, p_bottomToCoG_left, 20, new Scalar(0, 100, 255), -1); + //Cv2.Circle(mat_dst, p_bottomToCoG_right, 20, new Scalar(0, 100, 255), -1); + //Cv2.Circle(mat_dst, p_bottomToCoG_center, 20, new Scalar(0, 0, 255), -1); + //Cv2.Line(mat_dst, new OpenCvSharp.Point(0, lefty), new OpenCvSharp.Point(mat_finalMask.Cols - 1, righty), new Scalar(0, 100, 255)); //近似直線 + //Cv2.Circle(mat_dst, p_bottom_3, 20, new Scalar(0, 0, 255), -1); + + // 破棄 + mat_dst.Dispose(); + mat_nonZeroCoordinates.Dispose(); + GC.Collect(); + + var li_dst = new List { p_left_3, p_apex_left_3, p_bottom_3, p_apex_right_3, p_right_3 }; + return li_dst; } - var p_bottom_3 = new OpenCvSharp.Point(bottom_x_3, bottom_y_3); - - //Cv2.Circle(mat_dst, p_topToCoG_left, 20, new Scalar(0, 100, 255), -1); - //Cv2.Circle(mat_dst, p_topToCoG_right, 20, new Scalar(0, 100, 255), -1); - //Cv2.Circle(mat_dst, p_topToCoG_center, 20, new Scalar(0, 0, 255), -1); - //Cv2.Circle(mat_dst, p_bottomToCoG_left, 20, new Scalar(0, 100, 255), -1); - //Cv2.Circle(mat_dst, p_bottomToCoG_right, 20, new Scalar(0, 100, 255), -1); - //Cv2.Circle(mat_dst, p_bottomToCoG_center, 20, new Scalar(0, 0, 255), -1); - //Cv2.Line(mat_dst, new OpenCvSharp.Point(0, lefty), new OpenCvSharp.Point(mat_finalMask.Cols - 1, righty), new Scalar(0, 100, 255)); //近似直線 - Cv2.Circle(mat_dst, p_bottom_3, 20, new Scalar(0, 0, 255), -1); - + else + { + return new List(); + } // DEBUG - Cv2.NamedWindow("dst", WindowMode.KeepRatio ^ WindowMode.AutoSize); - Cv2.ImShow("dst", mat_dst.Resize(new OpenCvSharp.Size((int)mat_dst.Width * 0.5, (int)mat_dst.Height * 0.5))); - - // 出力 - // li_dst = new List { p_left, p_apex_left, p_bottom, p_apex_right, p_right }; - li_dst = new List { p_left_2, p_apex_left_2, p_bottom_2, p_apex_right_2, p_right_2 }; - - // 破棄 - mat_dst.Dispose(); - mat_nonZeroCoordinates.Dispose(); - GC.Collect(); - return li_dst; + //Cv2.NamedWindow("dst", WindowMode.KeepRatio ^ WindowMode.AutoSize); + //Cv2.ImShow("dst", mat_dst.Resize(new OpenCvSharp.Size((int)mat_dst.Width * 0.5, (int)mat_dst.Height * 0.5))); + } - private List Get8area(List list_5points) + public List Get8area(List list_5points) { var li_dst = new List(); // ROIマスク画像1 @@ -351,7 +365,7 @@ return li_dst; } - private List Get8colors(Mat mat_maskedImg, List list_8area) + public List Get8colors(Mat mat_maskedImg, List list_8area) { List li_dst = new List(); for (int i = 0; i < list_8area.Count(); i++) @@ -369,7 +383,7 @@ return li_dst; } - private void Show8area(Mat oriImg, List list_8area) + public void Show8area(Mat oriImg, List list_8area) { Cv2.Circle(oriImg, list_8area[0], 10, new Scalar(0, 255, 0), -1); Cv2.Circle(oriImg, list_8area[1], 10, new Scalar(0, 255, 0), -1); @@ -383,7 +397,7 @@ Cv2.ImShow("dst_", oriImg.Resize(new OpenCvSharp.Size((int)oriImg.Width * 0.5, (int)oriImg.Height * 0.5))); } - private List Calc8Lab(List list_8colors, string path_calibCsv, string path_colorMatrixXYZ) + public List Calc8Lab(List list_8colors, string path_calibCsv, string path_colorMatrixXYZ) { GetColorMatrixRGB(path_calibCsv); CalcTransMat(path_colorMatrixXYZ); @@ -401,7 +415,7 @@ return li_dst; } - private void GetColorMatrixRGB(string path_calibCsv) + public void GetColorMatrixRGB(string path_calibCsv) { System.Text.Encoding encoding = GetType(path_calibCsv); System.IO.FileStream fs3 = new System.IO.FileStream(path_calibCsv, System.IO.FileMode.Open, System.IO.FileAccess.Read); @@ -426,7 +440,7 @@ fs3.Close(); } - private void CalcTransMat(string path_colorMatrixXYZ) + public void CalcTransMat(string path_colorMatrixXYZ) { Mat RGBmat = new Mat(24, 17, MatType.CV_64F, new Scalar(1.0f)); Mat XYZmat = new Mat(24, 4, MatType.CV_64F, new Scalar(1.0f)); @@ -502,7 +516,7 @@ CSV_data.Close(); } - private void Read_TranslationMatrix() + public void Read_TranslationMatrix() { // 変換行列を読み込みなおす System.Text.Encoding encoding = GetType("translateMatrix.csv"); @@ -587,21 +601,6 @@ return new OpenCvSharp.Scalar(cL, ca, cb); } - private void Show8colors(List list_8Bgr, List list_8Lab) - { - Invoke((MethodInvoker)delegate - { - textBox1.Text = list_8Bgr[0].ToString() + " " + list_8Bgr[1].ToString(); - textBox2.Text = list_8Bgr[2].ToString() + " " + list_8Bgr[3].ToString(); - textBox3.Text = list_8Bgr[4].ToString() + " " + list_8Bgr[5].ToString(); - textBox4.Text = list_8Bgr[6].ToString() + " " + list_8Bgr[7].ToString(); - textBox5.Text = list_8Lab[0].ToString() + " " + list_8Lab[1].ToString(); - textBox6.Text = list_8Lab[2].ToString() + " " + list_8Lab[3].ToString(); - textBox7.Text = list_8Lab[4].ToString() + " " + list_8Lab[5].ToString(); - textBox8.Text = list_8Lab[6].ToString() + " " + list_8Lab[7].ToString(); - }); - } - private void Write8colors(List list_8Bgr, List list_8Lab) { // 保存 @@ -725,6 +724,5 @@ } return true; } - } } diff --git a/Tongue extraction_cropresizemethod/Tongue extraction/Form1.Designer.cs b/Tongue extraction_cropresizemethod/Tongue extraction/Form1.Designer.cs index 277b527..0cd08c7 100644 --- a/Tongue extraction_cropresizemethod/Tongue extraction/Form1.Designer.cs +++ b/Tongue extraction_cropresizemethod/Tongue extraction/Form1.Designer.cs @@ -32,6 +32,9 @@ this.button_start = new System.Windows.Forms.Button(); this.pictureBox_extraction = new System.Windows.Forms.PictureBox(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.panel3 = new System.Windows.Forms.Panel(); + this.label9 = new System.Windows.Forms.Label(); + this.comboBox_mode = new System.Windows.Forms.ComboBox(); this.label_mode = new System.Windows.Forms.Label(); this.panel1 = new System.Windows.Forms.Panel(); this.pictureBox_detection = new System.Windows.Forms.PictureBox(); @@ -54,11 +57,9 @@ this.panel2 = new System.Windows.Forms.Panel(); this.button_pause = new System.Windows.Forms.Button(); this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); - this.panel3 = new System.Windows.Forms.Panel(); - this.comboBox_mode = new System.Windows.Forms.ComboBox(); - this.label9 = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox_extraction)).BeginInit(); this.tableLayoutPanel1.SuspendLayout(); + this.panel3.SuspendLayout(); this.panel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox_detection)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox_input)).BeginInit(); @@ -68,7 +69,6 @@ ((System.ComponentModel.ISupportInitialize)(this.pictureBox_maskSRG)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox_last)).BeginInit(); this.panel2.SuspendLayout(); - this.panel3.SuspendLayout(); this.SuspendLayout(); // // button_start @@ -144,6 +144,42 @@ this.tableLayoutPanel1.Size = new System.Drawing.Size(1018, 554); this.tableLayoutPanel1.TabIndex = 5; // + // panel3 + // + this.panel3.Controls.Add(this.label9); + this.panel3.Controls.Add(this.comboBox_mode); + this.panel3.Dock = System.Windows.Forms.DockStyle.Left; + this.panel3.Location = new System.Drawing.Point(511, 478); + this.panel3.Margin = new System.Windows.Forms.Padding(1, 2, 1, 2); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(246, 49); + this.panel3.TabIndex = 23; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Dock = System.Windows.Forms.DockStyle.Fill; + this.label9.Font = new System.Drawing.Font("Arial Narrow", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label9.Location = new System.Drawing.Point(0, 0); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(47, 24); + this.label9.TabIndex = 1; + this.label9.Text = "Input"; + // + // comboBox_mode + // + this.comboBox_mode.Dock = System.Windows.Forms.DockStyle.Bottom; + this.comboBox_mode.FormattingEnabled = true; + this.comboBox_mode.Items.AddRange(new object[] { + "Image", + "Image&Calib.csv", + "Image&Calib.csv&Mask"}); + this.comboBox_mode.Location = new System.Drawing.Point(0, 29); + this.comboBox_mode.Name = "comboBox_mode"; + this.comboBox_mode.Size = new System.Drawing.Size(246, 20); + this.comboBox_mode.TabIndex = 0; + this.comboBox_mode.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); + // // label_mode // this.label_mode.AutoSize = true; @@ -383,43 +419,6 @@ // backgroundWorker1 // this.backgroundWorker1.WorkerSupportsCancellation = true; - this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWorker1_DoWork); - // - // panel3 - // - this.panel3.Controls.Add(this.label9); - this.panel3.Controls.Add(this.comboBox_mode); - this.panel3.Dock = System.Windows.Forms.DockStyle.Left; - this.panel3.Location = new System.Drawing.Point(511, 478); - this.panel3.Margin = new System.Windows.Forms.Padding(1, 2, 1, 2); - this.panel3.Name = "panel3"; - this.panel3.Size = new System.Drawing.Size(246, 49); - this.panel3.TabIndex = 23; - // - // comboBox_mode - // - this.comboBox_mode.Dock = System.Windows.Forms.DockStyle.Bottom; - this.comboBox_mode.FormattingEnabled = true; - this.comboBox_mode.Items.AddRange(new object[] { - "Image", - "Image&Calib.csv", - "Image&Calib.csv&Mask"}); - this.comboBox_mode.Location = new System.Drawing.Point(0, 29); - this.comboBox_mode.Name = "comboBox_mode"; - this.comboBox_mode.Size = new System.Drawing.Size(246, 20); - this.comboBox_mode.TabIndex = 0; - this.comboBox_mode.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); - // - // label9 - // - this.label9.AutoSize = true; - this.label9.Dock = System.Windows.Forms.DockStyle.Fill; - this.label9.Font = new System.Drawing.Font("Arial Narrow", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label9.Location = new System.Drawing.Point(0, 0); - this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(47, 24); - this.label9.TabIndex = 1; - this.label9.Text = "Input"; // // Form1 // @@ -436,6 +435,8 @@ ((System.ComponentModel.ISupportInitialize)(this.pictureBox_extraction)).EndInit(); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); + this.panel3.ResumeLayout(false); + this.panel3.PerformLayout(); this.panel1.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.pictureBox_detection)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox_input)).EndInit(); @@ -445,8 +446,6 @@ ((System.ComponentModel.ISupportInitialize)(this.pictureBox_maskSRG)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox_last)).EndInit(); this.panel2.ResumeLayout(false); - this.panel3.ResumeLayout(false); - this.panel3.PerformLayout(); this.ResumeLayout(false); } diff --git a/Tongue extraction_cropresizemethod/Tongue extraction/Form1.cs b/Tongue extraction_cropresizemethod/Tongue extraction/Form1.cs index dc370ee..f23e387 100644 --- a/Tongue extraction_cropresizemethod/Tongue extraction/Form1.cs +++ b/Tongue extraction_cropresizemethod/Tongue extraction/Form1.cs @@ -3,12 +3,14 @@ using System.IO; using System.Drawing; using System.Drawing.Imaging; -using OpenCvSharp; using System.ComponentModel; using System.Runtime.InteropServices; -using TensorFlow; using System.Threading; using System.Diagnostics; +using System.Linq; +using System.Collections.Generic; +using TensorFlow; +using OpenCvSharp; namespace Tongue_extraction { @@ -32,7 +34,6 @@ Mat mat_outputSRGNoBox = new Mat(1024, 1280, MatType.CV_8UC1, 1); Mat mat_outputSRG = new Mat(1024, 1280, MatType.CV_8UC1, 1); Mat mat_maskSRG = new Mat(1024, 1280, MatType.CV_8UC1, 1); - Mat mat_gloss = new Mat(1024, 1280, MatType.CV_8UC1, 1); public static Bitmap bitmap_bitch; string[] path; @@ -70,27 +71,15 @@ { InitializeComponent(); - // boundingboxなどのinfo出力用 - sw = new StreamWriter(fileName_info, false, System.Text.Encoding.GetEncoding("shift_jis")); - sw.WriteLine( - "image" + "," + - "top left X" + "," + "top left Y" + "," + "bottom right X" + "," + "bottom right Y" + "," + - "Width" + "," + "Height" + "," + "Area" + "," + "Gloss Count"); } private void Form1_Load(object sender, EventArgs e) { - comboBox_mode.SelectedIndex = 0; - } - - [Conditional("DEBUG")] - private void ShowDebugBox() - { + comboBox_mode.SelectedIndex = 1; } private void Button_start_Click(object sender, EventArgs e) { - ShowDebugBox(); path = Directory.GetFiles("data"); button_start.Enabled = false; button_pause.Enabled = true; @@ -110,7 +99,28 @@ pictureBox_extraction.Refresh(); pictureBox_last.Image = null; pictureBox_last.Refresh(); - backgroundWorker1.RunWorkerAsync(); + comboBox_mode.Enabled = false; + + if (comboBox_mode.SelectedIndex == 0) + { + this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWorker1_DoWork_Image); + backgroundWorker1.RunWorkerAsync(); + } + else if (comboBox_mode.SelectedIndex == 1) + { + this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWorker1_DoWork_ImageandCalib); + backgroundWorker1.RunWorkerAsync(); + } + else if (comboBox_mode.SelectedIndex == 2) + { + //this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWorker1_DoWork_MaskImage); + //backgroundWorker1.RunWorkerAsync(); + MessageBox.Show("This mode is not implemented."); + } + else + { + MessageBox.Show("Please select the mode on the combobox"); + } } public static class ImageUtil @@ -278,7 +288,7 @@ private static string DownloadDefaultModel(string dir) { - var modelFile = Path.Combine(dir, "2120_256_64_42999_enhancment_L1loss0.03435.pb"); + var modelFile = Path.Combine(dir, "AREinProcess2_step8100.pb"); return modelFile; } @@ -336,9 +346,16 @@ return bmp; } - private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e) + private void BackgroundWorker1_DoWork_Image(object sender, DoWorkEventArgs e) { + // boundingboxなどのinfo出力用 + sw = new StreamWriter(fileName_info, false, System.Text.Encoding.GetEncoding("shift_jis")); + sw.WriteLine( + "image" + "," + + "top left X" + "," + "top left Y" + "," + "bottom right X" + "," + "bottom right Y" + "," + + "Width" + "," + "Height" + "," + "Area" + "," + "Gloss Count"); + using (MemoryStream ms = new MemoryStream()) { for (int a = 0; a < path.Length; a++) @@ -571,59 +588,6 @@ label7.BackColor = Color.Red; - mat_gloss = mat_input.Clone(); - double sum = 0.0; - double sumsq = 0.0; - double avg = 0.0; - double stdev = 0.0; - for (int i = 0; i < mat_input.Height; i++) - { - for (int j = 0; j < mat_input.Width; j++) - { - var g_value = mat_gloss.At(i, j).Item1; - if (mat_maskSRG.At(i, j) == 0) - { - } - else - { - sum += g_value; // G チャンネル の和 - sumsq += g_value * g_value; // G チャンネル の平方和 - } - } - } - avg = (double)(sum / areaCount); // G チャンネル の平均 - stdev = Math.Sqrt(Math.Abs((sumsq / areaCount) - (avg * avg))); // 標準偏差 - double thresh = avg + (stdev * 2.0); - int glossCount = 0; - for (int i = 0; i < mat_input.Height; i++) - { - for (int j = 0; j < mat_input.Width; j++) - { - if (mat_maskSRG.At(i, j) == 0) - { - } - else - { - Vec3b pix = mat_gloss.At(i, j); - if (pix.Item1 > thresh) - { - glossCount++; - pix[0] = (byte)(255); - pix[1] = (byte)(0); - pix[2] = (byte)(0); - mat_gloss.Set(i, j, pix); - } - } - - } - } - mat_gloss.SaveImage(basepath + "\\gloss" + imageFile); - bitmap_bitch = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat_gloss); - Invoke((MethodInvoker)delegate - { - pictureBox_last.Image = bitmap_bitch; - pictureBox_last.Refresh(); - }); label7.BackColor = Color.White; @@ -696,11 +660,11 @@ var tensor = ImageUtil2.CreateTensorFromImageFile(byte_inputSegmentation); var runner = session.GetRunner(); runner - //.AddInput(graph["generator/input_image"][0], tensor) - //.Fetch(graph["generator/prediction"][0]); + .AddInput(graph["generator/input_image"][0], tensor) + .Fetch(graph["generator/prediction"][0]); - .AddInput(graph["input_image"][0], tensor) - .Fetch(graph["generator1/decoder_1/Tanh"][0]); + //.AddInput(graph["input_image"][0], tensor) + //.Fetch(graph["generator1/decoder_1/Tanh"][0]); var output = runner.Run(); float[,,,] resultfloat = (float[,,,])output[0].GetValue(jagged: false); @@ -843,73 +807,6 @@ // Gloss抽出処理 // extraction結果は使用しない(255,255,255の扱いが煩雑なため) label7.BackColor = Color.Red; - mat_gloss = mat_input.Clone(); - double sum = 0.0; - double sumsq = 0.0; - double avg = 0.0; - double stdev = 0.0; - // 2010石川さんの手法にならい,Gchannelのavgとstdを計算 - for (int i = 0; i < mat_input.Height; i++) - { - for (int j = 0; j < mat_input.Width; j++) - { - var g_value = mat_gloss.At(i, j).Item1; - if (mat_maskSRG.At(i, j) == 0) - { - } - else - { - sum += g_value; // G チャンネル の和 - sumsq += g_value * g_value; // G チャンネル の平方和 - } - } - } - avg = (double)(sum / areaCount); // G チャンネル の平均 - stdev = Math.Sqrt(Math.Abs((sumsq / areaCount) - (avg * avg))); // 標準偏差 - - // 閾値を決定し,glossをカウント - double thresh = avg + (stdev * 2.0); - int glossCount = 0; - for (int i = 0; i < mat_input.Height; i++) - { - for (int j = 0; j < mat_input.Width; j++) - { - Vec3b pix = mat_gloss.At(i, j); - if (mat_maskSRG.At(i, j) == 0) - { - pix[0] = (byte)((pix[0] + pix[1] + pix[2]) / 3); - pix[1] = (byte)pix[0]; - pix[2] = (byte)pix[0]; - mat_gloss.Set(i, j, pix); - } - else - { - if (pix.Item1 > thresh) - { - glossCount++; - pix[0] = (byte)(255); - pix[1] = (byte)(0); - pix[2] = (byte)(255); - mat_gloss.Set(i, j, pix); - } - else - { - pix[0] = (byte)((pix[0] + pix[1] + pix[2]) / 3); - pix[1] = (byte)pix[0]; - pix[2] = (byte)pix[0]; - mat_gloss.Set(i, j, pix); - } - } - - } - } - mat_gloss.SaveImage(basepath + "\\gloss" + imageFile); - bitmap_bitch = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat_gloss); - Invoke((MethodInvoker)delegate - { - pictureBox_last.Image = bitmap_bitch; - pictureBox_last.Refresh(); - }); label7.BackColor = Color.White; // 処理が終わった画像を記録する @@ -924,7 +821,7 @@ + P1.X.ToString() + "," + P1.Y.ToString() + "," + P2.X.ToString() + "," + P2.Y.ToString() + "," + Math.Abs(P1.X - P2.X).ToString() + "," + Math.Abs(P1.Y - P2.Y).ToString() + "," - + areaCount.ToString() + "," + glossCount.ToString() + + areaCount.ToString() + "," ); } GC.Collect(); @@ -940,6 +837,385 @@ } } + private void BackgroundWorker1_DoWork_ImageandCalib(object sender, DoWorkEventArgs e) + { + + // boundingboxなどのinfo出力用 + sw = new StreamWriter(fileName_info, false, System.Text.Encoding.GetEncoding("shift_jis")); + // 出力用csvの準備 + //sw.WriteLine( + // "image" + "," + + // "top left X" + "," + "top left Y" + "," + "bottom right X" + "," + "bottom right Y" + "," + + // "Area" + "," + "Gloss Count"); + sw.Close(); + + using (MemoryStream ms = new MemoryStream()) + { + // ディレクトリglobの取得 + var glob_dir = Directory.GetDirectories("data"); + + for (int a = 0; a < glob_dir.Length; a++) + { + manualReset.WaitOne(); + + // 画像と校正ファイルのパス + var glob_file = Directory.GetFiles(glob_dir[a]); + var path_calib = glob_file.Where(n => n.Contains("csv")).ToList()[0]; + var path_image = glob_file.Where(n => n.Contains("bmp") || n.Contains("png")).ToList()[0]; + var path_base = Directory.GetCurrentDirectory(); + var name_image = Path.GetFileName(path_image); + + // ステータスの表示 + Invoke((MethodInvoker)delegate + { + label_processingFileName.Text = "Processing File: " + "\\" + name_image; + count = a + 1; + label_totalProgress.Text = "Total Progress: " + count + "/" + glob_dir.Length; + }); + + // 入力画像読み込み・表示 + mat_input = Cv2.ImRead(path_image, ImreadModes.Color); + bitmap_bitch = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat_input); + Invoke((MethodInvoker)delegate + { + pictureBox_input.Image = bitmap_bitch; + pictureBox_input.Refresh(); + }); + + // Detection + label8.BackColor = Color.White; + label1.BackColor = Color.Red; + mat_drawBox = mat_input.Clone(); + mat_cropped = new Mat(mat_input.Size(), MatType.CV_8UC3, 1); + byte_inputDetection = Bitmap2Byte(bitmap_bitch); + using (var graph = new TFGraph()) + { + var model = File.ReadAllBytes(path_base + "/Detection_Normal.pb"); + graph.Import(model, ""); + + using (var session = new TFSession(graph)) + { + var tensor = ImageUtil.CreateTensorFromImageFile(byte_inputDetection, TFDataType.UInt8); + + var runner = session.GetRunner(); + runner + .AddInput(graph["image_tensor"][0], tensor) + .Fetch("detection_boxes", "detection_scores", "detection_classes", "num_detections"); + + var output = runner.Run(); + var boxes = (float[,,])output[0].GetValue(); + var scores = (float[,])output[1].GetValue(); + var classes = (float[,])output[2].GetValue(); + var detections = (float[])output[3].GetValue(); + check_detection = 0; + max_score = 0; + for (int i = 0; i < scores.Length; i++) + { + if ((scores[0, i] > 0.5) && (scores[0, i] > max_score)) + { + max_score = scores[0, i]; + float y_min = boxes[0, i, 0] * (float)bitmap_bitch.Height; + float x_min = boxes[0, i, 1] * (float)bitmap_bitch.Width; + float y_max = boxes[0, i, 2] * (float)bitmap_bitch.Height; + float x_max = boxes[0, i, 3] * (float)bitmap_bitch.Width; + P1.X = (int)x_min; + P1.Y = (int)y_min; + P2.X = (int)x_max; + P2.Y = (int)y_max; + Cv2.Rectangle(mat_drawBox, P1, P2, new Scalar(0, 255, 0), 5); + rectangle.X = (int)x_min; + rectangle.Y = (int)y_min; + rectangle.Width = (int)(x_max - x_min); + rectangle.Height = (int)(y_max - y_min); + + check_detection = 1; + } + } + } + } + // Detection結果表示・保存 + mat_drawBox.SaveImage(path_base + "\\detection" + "\\" + name_image); + bitmap_bitch = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat_drawBox); + Invoke((MethodInvoker)delegate + { + pictureBox_detection.Image = bitmap_bitch; + pictureBox_detection.Refresh(); + }); + label1.BackColor = Color.White; + + // 舌検出領域でcrop + label2.BackColor = Color.Red; + for (int i = P1.Y; i < P2.Y; i++) + { + for (int j = P1.X; j < P2.X; j++) + { + Vec3b pix = mat_input.At(i, j); + mat_cropped.Set(i, j, pix); + } + } + mat_cropped.SaveImage(path_base + "\\cropped" + "\\" + name_image); + + // 舌検出領域でresize + OpenCvSharp.Size size_roi = new OpenCvSharp.Size(); + size_roi.Height = rectangle.Height; + size_roi.Width = rectangle.Width; + roi = new Rect(P1, size_roi); + mat_roisize = mat_input.Clone(roi); + Cv2.Resize(mat_roisize, mat_roi, mat_roi256.Size()); + mat_roi.SaveImage(path_base + "\\cropresized" + "\\" + name_image); + bitmap_bitch = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat_roi); + Invoke((MethodInvoker)delegate + { + pictureBox_cropResized.Image = bitmap_bitch; + pictureBox_cropResized.Refresh(); + }); + label2.BackColor = Color.White; + + // Segmenation + label3.BackColor = Color.Red; + byte_inputSegmentation = Bitmap2Byte(bitmap_bitch); + Thread.Sleep(1000); + modelFile = DownloadDefaultModel(path_base); + ii = 0; + using (var graph = new TFGraph()) + { + var model = File.ReadAllBytes(modelFile); + graph.Import(model, ""); + + using (var session = new TFSession(graph)) + { + var tensor = ImageUtil2.CreateTensorFromImageFile(byte_inputSegmentation); + var runner = session.GetRunner(); + runner + .AddInput(graph["generator/input_image"][0], tensor) + .Fetch(graph["generator/prediction"][0]); + + //.AddInput(graph["input_image"][0], tensor) + //.Fetch(graph["generator1/decoder_1/Tanh"][0]); + + var output = runner.Run(); + float[,,,] resultfloat = (float[,,,])output[0].GetValue(jagged: false); + + for (int p = 0; p < 256; p++) + { + for (int q = 0; q < 256; q++) + { + float check = resultfloat[0, p, q, 0]; + if (check < 0) + { + mask[ii] = 0; + } + else + { + mask[ii] = 255; + } + ii++; + } + } + } + } + GC.Collect(); + Thread.Sleep(1000); + + // segmentation結果表示・保存 + bitmap_bitch = ToGrayBitmap(mask, 256, 256); + mat_output = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap_bitch); + bitmap_bitch = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat_output); + Invoke((MethodInvoker)delegate + { + pictureBox_output.Image = bitmap_bitch; + pictureBox_output.Refresh(); + }); + label3.BackColor = Color.White; + label4.BackColor = Color.Red; + mat_output.SaveImage(path_base + "\\output256" + "\\" + name_image); + + // 後処理(領域拡張法)でノイズ除去 iteration 2 + try + { + RemoveSmallRegion(path_base + "\\output256" + "\\" + name_image, path_base + "\\output_changed1" + "\\" + name_image, 500, 1, 1); + RemoveSmallRegion(path_base + "\\output_changed1" + "\\" + name_image, path_base + "\\output_changed2" + "\\" + name_image, 500, 0, 0); + } + catch + { + MessageBox.Show("Error: Unable to reprocess! Please check is there [RemoveSmallRegionDLL.dll] file in floder?", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + break; + } + mat_outputSRG = new Mat(path_base + "\\output_changed2" + "\\" + name_image, ImreadModes.GrayScale); + bitmap_bitch = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat_outputSRG); + Invoke((MethodInvoker)delegate + { + pictureBox_outputSRG.Image = bitmap_bitch; + pictureBox_outputSRG.Refresh(); + }); + label4.BackColor = Color.White; + label5.BackColor = Color.Red; + + // バウンディングボックスのサイズに戻す + Cv2.Resize(mat_outputSRG, mat_outputChanged, mat_roisize.Size()); + mat_outputChanged.SaveImage(path_base + "\\output_resized" + "\\" + name_image); + + // 入力と同じサイズでマスクを作成 + mat_mask = new Mat(mat_input.Size(), MatType.CV_8UC1, 1); + for (int i = P1.Y; i < P2.Y; i++) + { + for (int j = P1.X; j < P2.X; j++) + { + int pix = mat_outputChanged.At(mmp, pmm); + mat_mask.Set(i, j, pix); + pmm++; + } + mmp++; + pmm = 0; + } + mmp = 0; + Cv2.Resize(mat_mask, mat_mask, mat_input.Size()); + mat_mask.SaveImage(path_base + "\\mask" + "\\" + name_image); + + // ノイズ処理 + try + { + RemoveSmallRegion(path_base + "\\mask" + "\\" + name_image, path_base + "\\mask_changed1" + "\\" + name_image, 500, 1, 1); + RemoveSmallRegion(path_base + "\\mask_changed1" + "\\" + name_image, path_base + "\\mask_changed2" + "\\" + name_image, 500, 0, 0); + } + catch + { + MessageBox.Show("Error: Unable to reprocess! Please check is there [RemoveSmallRegionDLL.dll] file in floder?", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + break; + } + mat_maskSRG = new Mat(path_base + "\\mask_changed2" + "\\" + name_image, ImreadModes.GrayScale); + Cv2.Threshold(mat_maskSRG, mat_maskSRG, 128, 255, ThresholdTypes.Binary); + + // 2値マスクの最終結果 + mat_maskSRG.SaveImage(path_base + "\\mask_final" + "\\" + name_image); + bitmap_bitch = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat_maskSRG); + Invoke((MethodInvoker)delegate + { + pictureBox_maskSRG.Image = bitmap_bitch; + pictureBox_maskSRG.Refresh(); + }); + label5.BackColor = Color.White; + + // 元画像とマスクを合わせて,舌領域を抜き出す  + // todo: opencv等によるマスク処理と領域計算へ + label6.BackColor = Color.Red; + mat_extraction = mat_input.Clone(); + areaCount = 0; + for (int i = 0; i < mat_input.Height; i++) + { + for (int j = 0; j < mat_input.Width; j++) + { + Vec3b pix = mat_extraction.At(i, j); + if (mat_maskSRG.At(i, j) == 0) + { + pix[0] = (byte)(255); + pix[1] = (byte)(255); + pix[2] = (byte)(255); + mat_extraction.Set(i, j, pix); + } + else + { + pix[0] = (byte)(mat_extraction.At(i, j).Item0); + pix[1] = (byte)(mat_extraction.At(i, j).Item1); + pix[2] = (byte)(mat_extraction.At(i, j).Item2); + mat_extraction.Set(i, j, pix); + areaCount++; + } + } + } + mat_extraction.SaveImage(path_base + "\\extraction" + "\\" + name_image); + bitmap_bitch = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat_extraction); + Invoke((MethodInvoker)delegate + { + pictureBox_extraction.Image = bitmap_bitch; + pictureBox_extraction.Refresh(); + }); + label6.BackColor = Color.White; + + + /// 5点クリックによる色抽出処理 + var path_colorMatrixXYZ = "xyz.txt"; + + // 色抽出処理のクラス + ColorExtractor ce = new ColorExtractor(); + + // マスクされた舌領域画像の作成 + Mat mat_finalMask = mat_maskSRG.Clone(); + Mat mat_maskedImg = new Mat(); + mat_input.CopyTo(mat_maskedImg, mat_finalMask); + + // 5点クリック法(2010石川) + List list_5points_1 = ce.Get5points(mat_finalMask, ColorExtractor.FivePointMethod.Method1); + List list_5points_2 = ce.Get5points(mat_finalMask, ColorExtractor.FivePointMethod.Method1); + List list_5points_3 = ce.Get5points(mat_finalMask, ColorExtractor.FivePointMethod.Method1); + + // 8領域の取得 + List list_8area_1 = ce.Get8area(list_5points_1); + List list_8area_2 = ce.Get8area(list_5points_2); + List list_8area_3 = ce.Get8area(list_5points_3); + //ce.Show8area(mat_oriImg.Clone(), list_8area); + + //// 色抽出 + //List list_8Bgr = ce.Get8colors(mat_maskedImg, list_8area); + + //// 色変換(RGB->XYZ->Lab) + //List list_8Lab = ce.Calc8Lab(list_8Bgr, path_calib, path_colorMatrixXYZ); + + // 保存 + // Write8colors(list_8Bgr, list_8Lab); + + // 廃棄 + mat_finalMask.Dispose(); + mat_maskedImg.Dispose(); + GC.Collect(); + System.Threading.Thread.Sleep(100); + //bitmap_bitch = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat_gloss); + //Invoke((MethodInvoker)delegate + //{ + // pictureBox_last.Image = bitmap_bitch; + // pictureBox_last.Refresh(); + //}); + //label7.BackColor = Color.White; + + // 処理log + label8.BackColor = Color.Red; + time = DateTime.Now.ToLocalTime().ToString(); + File.AppendAllText("Log.txt ", time + " " + "\\" + name_image + " Done!\n"); + + // info出力 + sw = new StreamWriter(fileName_info, true, System.Text.Encoding.GetEncoding("shift_jis")); + sw.Write( + name_image.ToString() + "," + // bounding box + + P1.X.ToString() + "," + P1.Y.ToString() + "," + + P2.X.ToString() + "," + P2.Y.ToString() + "," + // area + + areaCount.ToString() + "," + ); + foreach (var n in list_8area_1) + sw.Write(n.X + "," + n.Y + ","); + foreach (var n in list_8area_2) + sw.Write(n.X + "," + n.Y + ","); + foreach (var n in list_8area_3) + sw.Write(n.X + "," + n.Y + ","); + sw.Write("\n"); + + sw.Close(); + // 破棄 + + } + GC.Collect(); + MessageBox.Show("Finished!"); + + Invoke((MethodInvoker)delegate + { + button_start.Enabled = true; + button_pause.Enabled = false; + label_processingFileName.Text = "Processing File: None"; + }); + } + } + private void Button_pause_Click(object sender, EventArgs e) { if (button_pause.Text == "Pause")