123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772 |
- using OpenCvSharp;
- using PaintDotNet.Adjust.BaseImage;
- using PaintDotNet.Base;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- namespace PaintDotNet.Adjust
- {
- /// <summary>
- /// 二值提取的处理程序
- /// </summary>
- public unsafe class BinaryExtractionIntent
- {
- /// <summary>
- /// 全局中间变量
- /// 不带视场的时候就是原图/二值图
- /// 带视场的时候就是原图/二值图
- /// </summary>
- public static Mat temp, temp_view;
- /// <summary>
- /// 用来存储透明图
- /// </summary>
- public static Mat alpha;
- /// <summary>
- /// 1个颜色区间还是2个
- /// </summary>
- public static int colorInterval;
- /// <summary>
- /// 1个颜色区间时的起始值
- /// </summary>
- public static int colorOneStart;
- /// <summary>
- /// 1个颜色区间时的结止值
- /// </summary>
- public static int colorOneEnd;
- /// <summary>
- /// 2个颜色区间时的第1个区间的起始值
- /// </summary>
- public static int colorTwoStart = 0;
- /// <summary>
- /// 2个颜色区间时的第1个区间的结止值
- /// </summary>
- public static int colorTwoEnd = 0;
- /// <summary>
- /// 2个颜色区间时的第2个区间的起始值
- /// </summary>
- public static int colorThreeStart = 0;
- /// <summary>
- /// 2个颜色区间时的第2个区间的起始值
- /// </summary>
- public static int colorThreeEnd = 0;
- //碎屑删除面积起
- public static int debrisAreaStart = 0;
- //碎屑删除面积止
- public static int debrisAreaEnd = 0;
- /// <summary>
- /// 默认相颜色
- /// </summary>
- public static Vec4b vec4B = new Vec4b(255, 0, 0, 255);
- /// <summary>
- /// 新增的参数,用于FloodFill方法
- /// </summary>
- public static Rect rect;
- /// <summary>
- /// 各个连通域的代表点
- /// </summary>
- public static List<OpenCvSharp.Point> points;
- /// <summary>
- /// 用来记录需要删除的连通区域的编号
- /// </summary>
- public static Dictionary<int, int> keyValuePairs = new Dictionary<int, int>();
- public static Mat rgb_ap;
- public static Mat temp_ap;
- #region 无视场 二值提取
- /// <summary>
- /// 二值操作-二值提取-无视场
- /// </summary>
- /// <param name="src">源图像</param>
- /// <param name="lists">参数集合</param>
- /// <returns></returns>
- public static Mat ImageBinaryExtraction(Mat src, List<Args> lists, bool findContours = false)
- {
- //以下是参数信息---------------------
- ///1个颜色区间还是2个
- colorInterval = 1;
- //第一个二值区间
- colorOneStart = 0;
- colorOneEnd = 0;
- //第二个二值区间
- colorTwoStart = 0;
- colorTwoEnd = 0;
- //第三个二值区间
- colorThreeStart = 0;
- colorThreeEnd = 0;
- //处理细节
- //删除边界对象
- bool deleteBoundaryObject = false;
- //孔洞填充
- bool holeFilling = false;
- //碎屑删除
- bool debrisRemoval = false;
- //碎屑删除面积起
- debrisAreaStart = 0;
- //碎屑删除面积止
- debrisAreaEnd = 0;
- //二值样式
- //1实心 2边线
- int binaryStyle = 0;
- //相颜色
- Color phaseColor = Color.Red;
- //目标选择
- int targetSelection = 1;
- for (int i = 0; i < lists.Count; i++)
- {
- Args args = lists[i];
- switch (args.Key)
- {
- case "colorInterval":
- {
- if (args.Value is Boolean)
- colorInterval = (Boolean)args.Value ? 2 : 1;
- else
- colorInterval = (int)args.Value;
- }
- break;
- case "scope1":
- colorOneStart = (int)((List<double>)args.Value)[0];
- colorOneEnd = (int)((List<double>)args.Value)[1];
- break;
- case "scope2":
- colorTwoStart = (int)((List<double>)args.Value)[0];
- colorTwoEnd = (int)((List<double>)args.Value)[1];
- break;
- case "scope3":
- colorThreeStart = (int)((List<double>)args.Value)[0];
- colorThreeEnd = (int)((List<double>)args.Value)[1];
- break;
- case "deleteBoundaryObject":
- deleteBoundaryObject = (bool)args.Value;
- break;
- case "holeFilling":
- holeFilling = (bool)args.Value;
- break;
- case "debrisRemoval":
- debrisRemoval = (bool)args.Value;
- break;
- case "binaryStyle":
- binaryStyle = (int)args.Value;
- break;
- case "phaseColor":
- phaseColor = Color.FromArgb((int)args.Value);
- break;
- case "targetSelection":
- targetSelection = (int)args.Value;
- break;
- case "scope4":
- debrisAreaStart = (int)((List<double>)args.Value)[0];
- debrisAreaEnd = (int)((List<double>)args.Value)[1];
- findContours = true;
- break;
- default:
- break;
- }
- }
- if (phaseColor.A < 1)//#21321
- phaseColor = Color.FromArgb(1, phaseColor.R, phaseColor.G, phaseColor.B);
- vec4B.Item0 = phaseColor.B;
- vec4B.Item1 = phaseColor.G;
- vec4B.Item2 = phaseColor.R;
- vec4B.Item3 = phaseColor.A;
- //中值滤波
- //Cv2.MedianBlur(src, src, 3);
- //二值提取
- src = Binarization(src);
- //删除边界对象
- if (deleteBoundaryObject)
- src = DeleteContours_New(src);
- //碎屑删除,参考冈萨雷斯,414,9.5.3,连通分量提取
- if (debrisRemoval && debrisAreaEnd > 0)
- src = DebrisRemoval_New(src);
- //孔洞填充,参考冈萨雷斯,413,9.5.2
- if (holeFilling)
- src = HoleFilling_New(src);
-
- //实心/边线,参考冈萨雷斯,412,9.5.1,边界提取
- if (binaryStyle == 2)
- {
- Cv2.Erode(src, temp, null);
- src = src - temp;
- src = BaseTools.MergeMatFromMatArr(src, vec4B);
- }
- return src;
- }
- /// <summary>
- /// 二值提取
- /// </summary>
- /// <param name="source">源</param>
- /// <param name="colorInterval">1个或2个颜色区间</param>
- /// <param name="colorOneStart"></param>
- /// <param name="colorOneEnd"></param>
- /// <param name="colorTwoStart"></param>
- /// <param name="colorTwoEnd"></param>
- /// <param name="colorThreeStart"></param>
- /// <param name="colorThreeEnd"></param>
- /// <returns></returns>
- private static Mat Binarization(Mat source)
- {
- Mat srcGray;
- if (source.Type() == MatType.CV_8UC1)
- {
- srcGray = source;
- }
- else
- {
- srcGray = source.CvtColor(ColorConversionCodes.BGR2GRAY);
- }
- temp = new Mat(source.Rows, source.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
- srcGray.ForEachAsByte(GrayForEachAsByte);
- return temp.Clone();
- }
- /// <summary>
- /// 并行循环
- /// </summary>
- /// <param name="value"></param>
- /// <param name="position"></param>
- private static void GrayForEachAsByte(byte* value, int* position)
- {
- int y = position[0];
- int x = position[1];
- byte v = *value;
- if (colorInterval == 1)
- {
- if (v >= colorOneStart && v <= colorOneEnd)
- {
- temp.Set<Vec4b>(y, x, vec4B);
- }
- }
- else
- {
- if ((v >= colorTwoStart && v <= colorTwoEnd) || (v >= colorThreeStart && v <= colorThreeEnd))
- {
- temp.Set<Vec4b>(y, x, vec4B);
- }
- }
- }
- /// <summary>
- /// 新版本删除边界
- /// </summary>
- /// <param name="src"></param>
- /// <returns></returns>
- private static Mat DeleteContours_New(Mat src)
- {
- Mat[] arr = src.Split();
- Mat rgb = BaseTools.MergeMatFromMatArr(arr);
- Mat temp_1 = arr[3].Clone();
- for (int h = 0; h < temp_1.Width; h++)
- {
- byte vec4B_top = temp_1.At<byte>(0, h);
- if (vec4B_top > 0)
- {
- Cv2.FloodFill(rgb, new OpenCvSharp.Point(h, 0), new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
- Cv2.FloodFill(temp_1, new OpenCvSharp.Point(h, 0), new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
- }
- }
- for (int h = 0; h < temp_1.Width; h++)
- {
- byte vec4B_bottom = temp_1.At<byte>(temp_1.Height - 1, h);
- if (vec4B_bottom > 0)
- {
- Cv2.FloodFill(rgb, new OpenCvSharp.Point(h, temp_1.Height - 1), new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
- Cv2.FloodFill(temp_1, new OpenCvSharp.Point(h, temp_1.Height - 1), new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
- }
- }
- for (int y = 0; y < temp_1.Height; y++)
- {
- Vec4b vec4B_top = temp_1.At<Vec4b>(y, 0);
- if (vec4B_top.Item3 > 0)
- {
- Cv2.FloodFill(rgb, new OpenCvSharp.Point(0, y), new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
- Cv2.FloodFill(temp_1, new OpenCvSharp.Point(0, y), new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
- }
- }
- for (int y = 0; y < temp_1.Height; y++)
- {
- byte vec4B_top = temp_1.At<byte>(y, temp_1.Width - 1);
- if (vec4B_top > 0)
- {
- Cv2.FloodFill(rgb, new OpenCvSharp.Point(temp_1.Width - 1, y), new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
- Cv2.FloodFill(temp_1, new OpenCvSharp.Point(temp_1.Width - 1, y), new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
- }
- }
- Mat[] mats = rgb.Split();
- arr[0] = mats[0];
- arr[1] = mats[1];
- arr[2] = mats[2];
- arr[3] = temp_1;
- Cv2.Merge(arr, src);
- return src;
- }
- /// <summary>
- /// 新孔洞填充,采用形态学填充
- /// </summary>
- /// <param name="src"></param>
- /// <returns></returns>
- private static Mat HoleFilling_New(Mat src)
- {
- Mat[] arr2 = src.Split();
- Mat matc = arr2[3];
- //去掉透明层
- Mat mat = src.CvtColor(ColorConversionCodes.BGRA2BGR);
- //填充孔洞
- mat = BaseTools.FillHole(mat, new Scalar(255-vec4B.Item0, 255 - vec4B.Item1, 255 - vec4B.Item2));
- matc = BaseTools.FillHole(matc, new Scalar(255));
- //循环处理
- mat.ForEachAsVec3b(RGBForEachAsByteForHoleFillingNew);
-
- Mat[] arr1 = mat.Split();
- arr2[0] = arr1[0];
- arr2[1] = arr1[1];
- arr2[2] = arr1[2];
- arr2[3] = matc;
- Cv2.Merge(arr2, src);
- return src;
- }
- private static void RGBForEachAsByteForHoleFillingNew(Vec3b* value, int* position)
- {
- int y = position[0];
- int x = position[1];
- if (value->Item0==255 && value->Item1==255 && value->Item2==255)
- {
- value->Item0 = vec4B.Item0;
- value->Item1 = vec4B.Item1;
- value->Item2 = vec4B.Item2;
- }
- }
- /// <summary>
- /// 新碎屑删除,使用连通分量找寻碎屑
- /// </summary>
- /// <param name="src"></param>
- /// <returns></returns>
- private static Mat DebrisRemoval_New(Mat src)
- {
- Mat[] arr = src.Split();
- rgb_ap = BaseTools.MergeMatFromMatArr(arr);
- temp_ap = arr[3].Clone();
- //寻找连通分量
- Mat labelMat = new Mat();
- Mat stats = new Mat();
- Mat centroids = new Mat();
- int nonenum = Cv2.ConnectedComponentsWithStats(temp_ap, labelMat, stats, centroids, PixelConnectivity.Connectivity8);
- //寻找在范围内需要删除的碎屑
- keyValuePairs.Clear();
- for (int h = 1; h < centroids.Height; h++)
- {
- int areaField1 = stats.At<int>(h, 4);
- if (debrisAreaStart <= areaField1 && areaField1 <= debrisAreaEnd)
- {
- keyValuePairs.Add(h, 1);
- }
- }
-
- labelMat.ForEachAsInt32(CommonForEachForInt32);
- //合并rgb和透明度
- Mat[] mats = rgb_ap.Split();
- arr[0] = mats[0];
- arr[1] = mats[1];
- arr[2] = mats[2];
- arr[3] = temp_ap;
- Cv2.Merge(arr, src);
- return src;
- }
- #endregion
- #region 有视场 二值提取
- /// <summary>
- /// 二值操作-二值提取-有视场
- /// </summary>
- /// <param name="src">视场mat</param>
- /// <param name="mat">原图mat</param>
- /// <param name="lists">参数列表</param>
- /// <returns></returns>
- public static Mat ImageBinaryExtraction(Mat source, Mat mat, List<Args> lists, bool findContours = false)
- {
- //以下是参数信息---------------------
- ///1个颜色区间还是2个
- colorInterval = 1;
- //第一个二值区间
- colorOneStart = 0;
- colorOneEnd = 0;
- //第二个二值区间
- colorTwoStart = 0;
- colorTwoEnd = 0;
- //第三个二值区间
- colorThreeStart = 0;
- colorThreeEnd = 0;
- //处理细节
- //删除边界对象
- bool deleteBoundaryObject = false;
- //孔洞填充
- bool holeFilling = false;
- //碎屑删除
- bool debrisRemoval = false;
- //碎屑删除面积起
- debrisAreaStart = 0;
- //碎屑删除面积止
- debrisAreaEnd = 0;
- //二值样式
- //1实心 2边线
- int binaryStyle = 0;
- //相颜色
- Color phaseColor = Color.Red;
- //目标选择
- int targetSelection = 1;
- for (int i = 0; i < lists.Count; i++)
- {
- Args args = lists[i];
- switch (args.Key)
- {
- case "colorInterval":
- {
- if (args.Value is Boolean)
- colorInterval = (Boolean)args.Value ? 2 : 1;
- else
- colorInterval = (int)args.Value;
- }
- break;
- case "scope1":
- colorOneStart = (int)((List<double>)args.Value)[0];
- colorOneEnd = (int)((List<double>)args.Value)[1];
- break;
- case "scope2":
- colorTwoStart = (int)((List<double>)args.Value)[0];
- colorTwoEnd = (int)((List<double>)args.Value)[1];
- break;
- case "scope3":
- colorThreeStart = (int)((List<double>)args.Value)[0];
- colorThreeEnd = (int)((List<double>)args.Value)[1];
- break;
- case "deleteBoundaryObject":
- deleteBoundaryObject = (bool)args.Value;
- break;
- case "holeFilling":
- holeFilling = (bool)args.Value;
- break;
- case "debrisRemoval":
- debrisRemoval = (bool)args.Value;
- break;
- case "binaryStyle":
- binaryStyle = (int)args.Value;
- break;
- case "phaseColor":
- phaseColor = Color.FromArgb((int)args.Value);
- break;
- case "targetSelection":
- targetSelection = (int)args.Value;
- break;
- case "scope4":
- debrisAreaStart = (int)((List<double>)args.Value)[0];
- debrisAreaEnd = (int)((List<double>)args.Value)[1];
- break;
- default:
- break;
- }
- }
- vec4B.Item0 = phaseColor.B;
- vec4B.Item1 = phaseColor.G;
- vec4B.Item2 = phaseColor.R;
- vec4B.Item3 = phaseColor.A;
- //二值提取
- Mat src = BinarizationWithView(source);
-
- //目标选择
- if (targetSelection != 2)
- src = CalcContoursByTargetSelection_New(temp_view, targetSelection, source);
- //碎屑删除,参考冈萨雷斯,414,9.5.3,连通分量提取
- if (debrisRemoval && debrisAreaEnd > 0)
- src = DebrisRemoval_NewWithView(src);
- //孔洞填充,参考冈萨雷斯,413,9.5.2
- if (holeFilling)
- src = HoleFilling_NewWithView(src);
- //实心/边线,参考冈萨雷斯,412,9.5.1,边界提取
- if (binaryStyle == 2)
- {
- Cv2.Erode(src, temp, null);
- src = src - temp;
- src = BaseTools.MergeMatFromMatArr(src, vec4B);
- }
- return src;
- }
- /// <summary>
- /// 二值提取
- /// </summary>
- /// <param name="source">视场图像</param>
- /// <param name="mat">原图像</param>
- /// <param name="colorInterval">1个或2个颜色区间</param>
- /// <param name="colorOneStart"></param>
- /// <param name="colorOneEnd"></param>
- /// <param name="colorTwoStart"></param>
- /// <param name="colorTwoEnd"></param>
- /// <param name="colorThreeStart"></param>
- /// <param name="colorThreeEnd"></param>
- /// <param name="phaseColor">相颜色</param>
- /// <returns></returns>
- private static Mat BinarizationWithView(Mat source)
- {
- Mat[] arr = source.Split();
- alpha = arr[3];
- Mat srcGray;
- if (source.Type() == MatType.CV_8UC1)
- {
- srcGray = source;
- }
- else
- {
- srcGray = source.CvtColor(ColorConversionCodes.BGR2GRAY);
- }
- temp_view = new Mat(source.Rows, source.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
- temp = new Mat(source.Rows, source.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
- srcGray.ForEachAsByte(GrayForEachAsByteWithView);
- return temp.Clone();
- }
- /// <summary>
- /// 并行循环
- /// </summary>
- /// <param name="value"></param>
- /// <param name="position"></param>
- private static void GrayForEachAsByteWithView(byte* value, int* position)
- {
- int y = position[0];
- int x = position[1];
- byte v = *value;
- if (colorInterval == 1)
- {
- if (v >= colorOneStart && v <= colorOneEnd)
- {
- if(alpha.At<byte>(y, x) > 0)
- {
- temp.Set<Vec4b>(y, x, vec4B);
- temp_view.Set<Vec4b>(y, x, vec4B);
- }
- else
- {
- temp_view.Set<Vec4b>(y, x, new Vec4b(vec4B.Item0, vec4B.Item1, vec4B.Item2,0));
- }
- }
- }
- else
- {
- if (((v >= colorTwoStart && v <= colorTwoEnd) || (v >= colorThreeStart && v <= colorThreeEnd)))
- {
- if (alpha.At<byte>(y, x) > 0)
- {
- temp.Set<Vec4b>(y, x, vec4B);
- temp_view.Set<Vec4b>(y, x, vec4B);
- }
- else
- {
- temp_view.Set<Vec4b>(y, x, new Vec4b(vec4B.Item0, vec4B.Item1, vec4B.Item2, 0));
- }
- }
- }
- }
- /// <summary>
- /// 新碎屑删除,使用连通分量找寻碎屑
- /// </summary>
- /// <param name="src"></param>
- /// <returns></returns>
- private static Mat DebrisRemoval_NewWithView(Mat src)
- {
- Mat[] arr = src.Split();
- rgb_ap = BaseTools.MergeMatFromMatArr(arr);
- temp_ap = arr[3].Clone();
- //寻找连通分量
- Mat labelMat = new Mat();
- Mat stats = new Mat();
- Mat centroids = new Mat();
- int nonenum = Cv2.ConnectedComponentsWithStats(temp_ap, labelMat, stats, centroids, PixelConnectivity.Connectivity8);
- //寻找在范围内需要删除的碎屑
- keyValuePairs.Clear();
- for (int h = 1; h < centroids.Height; h++)
- {
- int areaField1 = stats.At<int>(h, 4);
- if (debrisAreaStart <= areaField1 && areaField1 <= debrisAreaEnd)
- {
- keyValuePairs.Add(h, 1);
- }
- }
- labelMat.ForEachAsInt32(CommonForEachForInt32);
- //合并rgb和透明度
- Mat[] mats = rgb_ap.Split();
- arr[0] = mats[0];
- arr[1] = mats[1];
- arr[2] = mats[2];
- arr[3] = temp_ap;
- Cv2.Merge(arr, src);
- return src;
- }
- /// <summary>
- /// 新孔洞填充,采用形态学填充
- /// </summary>
- /// <param name="src"></param>
- /// <returns></returns>
- private static Mat HoleFilling_NewWithView(Mat src)
- {
- Mat[] arr2 = src.Split();
- Mat tempc = arr2[3];
-
- //去掉透明层
- Mat mat = src.CvtColor(ColorConversionCodes.BGRA2BGR);
- //填充孔洞
- mat = BaseTools.FillHole(mat, new Scalar(255 - vec4B.Item0, 255 - vec4B.Item1, 255 - vec4B.Item2));
- tempc = BaseTools.FillHole(tempc, new Scalar(255));
- //循环处理
- mat.ForEachAsVec3b(RGBForEachAsByteForHoleFillingNewWithView);
-
- Mat[] arr1 = mat.Split();
- arr2[0] = arr1[0];
- arr2[1] = arr1[1];
- arr2[2] = arr1[2];
- arr2[3] = tempc;
- Cv2.Merge(arr2, src);
- return src;
- }
- private static void RGBForEachAsByteForHoleFillingNewWithView(Vec3b* value, int* position)
- {
- int y = position[0];
- int x = position[1];
- if (value->Item0 == 255 && value->Item1 == 255 && value->Item2 == 255)
- {
- value->Item0 = vec4B.Item0;
- value->Item1 = vec4B.Item1;
- value->Item2 = vec4B.Item2;
- }
- }
- /// <summary>
- /// 目标选择
- /// </summary>
- /// <param name="src"></param>
- /// <param name="mat"></param>
- /// <param name="targetSelection"></param>
- /// <param name="source"></param>
- /// <returns></returns>
- public static Mat CalcContoursByTargetSelection_New(Mat src, int targetSelection, Mat source)
- {
- Mat[] arr = src.Split();
- alpha = arr[3].Clone();
- Mat rgb = BaseTools.MergeMatFromMatArr(arr);
- Mat alphatemp = arr[3].Clone();
- Mat mask = Mat.Zeros(rgb.Rows + 2, rgb.Cols + 2, MatType.CV_8UC1);
- //考虑循环填充,填充视场的透明层和原图的透明层,然后比较填充区域的大小
- //但是循环的时候需要少循环像素,可以处理视场的透明层,减少循环量
- //同时记录种子点,然后根据targetSelection判断是填充透明还是不透明
- Mat rgbClone = rgb.Clone();
- List<OpenCvSharp.Point> points = new List<OpenCvSharp.Point>();
- for(int h=0; h< alphatemp.Height; h++)
- {
- for (int w = 0; w < alphatemp.Width; w++)
- {
- int v = alphatemp.At<byte>(h, w);
- if(v>0)
- {
- int a = Cv2.FloodFill(alphatemp, new OpenCvSharp.Point(w, h), new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
- int b = Cv2.FloodFill(rgbClone, new OpenCvSharp.Point(w, h), new Scalar(0, 0, 0), out rect, null, null, FloodFillFlags.Link8);
- if(a !=b)
- {
- points.Add(new OpenCvSharp.Point(w, h));
- }
- }
- }
- }
-
- if(points.Count>0)
- {
- foreach(OpenCvSharp.Point p in points)
- {
- if(targetSelection == 1)
- {
- Cv2.FloodFill(alpha, p, new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
- }
- else if(targetSelection == 3)
- {
- Cv2.FloodFill(rgb, mask, p, new Scalar(vec4B.Item0, vec4B.Item1, vec4B.Item2), out rect, null, null, FloodFillFlags.Link8);
- }
- }
- }
- if (targetSelection == 3)
- {
- Mat t = new Mat(mask, new Rect(1, 1, rgb.Width, rgb.Height));
- alpha = alpha + t * 255;
- }
-
- //合并rgb和透明度
- Mat[] mats = rgb.Split();
- arr[0] = mats[0];
- arr[1] = mats[1];
- arr[2] = mats[2];
- arr[3] = alpha;
- Cv2.Merge(arr, src);
- return src;
- }
- #endregion
- private static void CommonForEachForInt32(int* value, int* position)
- {
- int y = position[0];
- int x = position[1];
- int v = *value;
- if (v > 0 && keyValuePairs.ContainsKey(v))
- {
- rgb_ap.Set<Vec3b>(y, x, new Vec3b(0, 0, 0));
- temp_ap.Set<int>(y, x, 0);
- }
- }
- }
- }
|