123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace OTSMeasureApp.ServiceCenter
- {
- using OpenCvSharp;
-
- public class ImageStitchUsingOpenCvSharp
- {
- #region 合并天宇颗粒融合新增函数
- public Mat CombinImageX(Mat[] list_mats, int OverlapParam, int type)
- {
- List<Mat> matStitch = new List<Mat>();//拼接
- List<Mat> matCombin = new List<Mat>();//合并
- for (int i = 0; i < list_mats.Count(); i++)
- {
- if (i == 0)//首张
- {
- matCombin.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(0, 0, list_mats[i].Width - OverlapParam - 100, list_mats[i].Height)));
- matStitch.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(list_mats[i].Width - OverlapParam - 100, 0, OverlapParam + 100, list_mats[i].Height)));
- }
- else if (i == list_mats.Count() - 1)//末张
- {
- matStitch.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(0, 0, OverlapParam + 100, list_mats[i].Height)));
- matCombin.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(OverlapParam + 100, 0, list_mats[i].Width - OverlapParam - 100, list_mats[i].Height)));
- }
- else
- {
- matStitch.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(0, 0, OverlapParam + 100, list_mats[i].Height)));
- matCombin.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(OverlapParam + 100, 0, list_mats[i].Width - (OverlapParam + 100) * 2, list_mats[i].Height)));
- matStitch.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(list_mats[i].Width - OverlapParam - 100, 0, OverlapParam + 100, list_mats[i].Height)));
- }
- }
- for (int i = 0; i < matStitch.Count; i += 2)
- {
- if (matStitch.Count == 1)
- {
- matCombin.Insert(i + 1, matStitch[i]);
- }
- else
- {
- matCombin.Insert(i + 1, StitchImageX((int)(OverlapParam / 2 * 1.2), type, matStitch[i], matStitch[i + 1]));
- }
- }
- Mat pano = new OpenCvSharp.Mat();
- Cv2.HConcat(matCombin.ToArray(), pano);
- return pano;
- }
- public Mat CombinImageY(Mat[] list_mats, int OverlapParam, int type)
- {
- List<Mat> matStitch = new List<Mat>();//拼接
- List<Mat> matCombin = new List<Mat>();//合并
- for (int i = 0; i < list_mats.Count(); i++)
- {
- if (i == 0)//首张
- {
- matCombin.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(0, 0, list_mats[i].Width, list_mats[i].Height - OverlapParam - 100)));
- matStitch.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(0, list_mats[i].Height - OverlapParam - 100, list_mats[i].Width, OverlapParam + 100)));
- }
- else if (i == list_mats.Count() - 1)//末张
- {
- matStitch.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(0, 0, list_mats[i].Width, OverlapParam + 100)));
- matCombin.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(0, OverlapParam + 100, list_mats[i].Width, list_mats[i].Height - OverlapParam - 100)));
- }
- else
- {
- matStitch.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(0, 0, list_mats[i].Width, OverlapParam + 100)));
- matCombin.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(0, OverlapParam + 100, list_mats[i].Width, list_mats[i].Height - (OverlapParam + 100) * 2)));
- matStitch.Add(new Mat(list_mats[i], new OpenCvSharp.Rect(0, list_mats[i].Height - OverlapParam - 100, list_mats[i].Width, OverlapParam + 100)));
- }
- }
- for (int i = 0; i < matStitch.Count; i += 2)
- {
- if (matStitch.Count == 1)
- {
- matCombin.Insert(i + 1, matStitch[i]);
- }
- else
- {
- matCombin.Insert(i + 1, StitchImageY(OverlapParam, type, matStitch[i], matStitch[i + 1]));
- }
- }
- Mat pano = new OpenCvSharp.Mat();
- Cv2.VConcat(matCombin.ToArray(), pano);
- return pano;
- }
- public struct MStitch
- {
- public int Pwidth;//单幅图像的宽度
- public int Pheight;//单幅图像的高度
- public int W_min;//最小的重叠区域宽度
- public int W_max;//最大的重叠区域宽度
- public int H_min;//最小的重叠区域高度
- public double minval;//块过滤阈值
- public Mat im;//图像信息
- }
- public struct ImageParam
- {
- public int W_box;//宽度信息
- public int H_box;//高度信息
- public int bdown;//上下信息
- public MStitch mStitch; //参数结构
- public Mat im;//图像信息
- }
- /// <summary>
- /// 横向拼图
- /// </summary>
- public Mat StitchImageXGrid(int min_w, int type, Mat newImg1, Mat newImg2)
- {
- MStitch mStitch = new MStitch();
- mStitch.Pwidth = newImg1.Width;
- mStitch.Pheight = newImg1.Height;
- mStitch.W_min = min_w - 50;
- mStitch.W_max = min_w + 50;
- mStitch.H_min = newImg1.Height;
- mStitch.minval = 255;
- mStitch.im = newImg1;
- ImageParam imageParam = Fun_Match(newImg2, mStitch);
- imageParam.im = newImg2;
- if (type == 3)
- {
- return Fun_Stitch(imageParam);
- }
- else
- {
- return Fun_StitchRGB(imageParam);
- }
- }
- /// <summary>
- /// 纵向拼图
- /// </summary>
- public Mat StitchImageYGrid(int min_w, int type, Mat newImg1, Mat newImg2)
- {
- Cv2.Transpose(newImg1, newImg1);
- Cv2.Flip(newImg1, newImg1, FlipMode.X);
- Cv2.Transpose(newImg2, newImg2);
- Cv2.Flip(newImg2, newImg2, FlipMode.X);
- MStitch mStitch = new MStitch();
- mStitch.Pwidth = newImg1.Width;
- mStitch.Pheight = newImg1.Height;
- mStitch.W_min = min_w - 50;
- mStitch.W_max = min_w + 50;
- mStitch.H_min = newImg1.Height;
- mStitch.minval = 255;
- mStitch.im = newImg1;
- ImageParam imageParam = Fun_Match(newImg2, mStitch);
- imageParam.im = newImg2;
- Mat result = type == 3 ? Fun_Stitch(imageParam) : Fun_StitchRGB(imageParam);
- Cv2.Transpose(result, result);
- Cv2.Flip(result, result, FlipMode.Y);
- return result;
- }
- /// <summary>
- /// 横向拼图
- /// </summary>
- public Mat StitchImageX(int min_w, int type, Mat newImg1, Mat newImg2)
- {
- MStitch mStitch = new MStitch();
- mStitch.Pwidth = newImg1.Width;
- mStitch.Pheight = newImg1.Height;
- mStitch.W_min = min_w;
- mStitch.W_max = min_w;
- mStitch.H_min = newImg1.Height;
- mStitch.minval = 255;
- mStitch.im = newImg1;
- ImageParam imageParam = Fun_Match(newImg2, mStitch);
- imageParam.im = newImg2;
- if (type == 3)
- {
- return Fun_Stitch(imageParam);
- }
- else
- {
- return Fun_StitchRGB(imageParam);
- }
- }
- /// <summary>
- /// 纵向拼图
- /// </summary>
- public Mat StitchImageY(int min_w, int type, Mat newImg1, Mat newImg2)
- {
- Cv2.Transpose(newImg1, newImg1);
- Cv2.Flip(newImg1, newImg1, FlipMode.X);
- Cv2.Transpose(newImg2, newImg2);
- Cv2.Flip(newImg2, newImg2, FlipMode.X);
- MStitch mStitch = new MStitch();
- mStitch.Pwidth = newImg1.Width;
- mStitch.Pheight = newImg1.Height;
- mStitch.W_min = min_w - 50;
- mStitch.W_max = min_w - 50;
- mStitch.H_min = newImg1.Height - 20;
- mStitch.minval = 255;
- mStitch.im = newImg1;
- ImageParam imageParam = Fun_Match(newImg2, mStitch);
- imageParam.im = newImg2;
- Mat result = type == 2 ? Fun_Stitch(imageParam) : Fun_StitchRGB(imageParam);
- Cv2.Transpose(result, result);
- Cv2.Flip(result, result, FlipMode.Y);
- return result;
- }
- public static ImageParam Fun_Match(Mat im2, MStitch mStitch)
- {
- ImageParam imageParam = new ImageParam();
- double imsum = 0;
- int x1 = 0;
- int y1 = 0;
- int x2 = 0;
- int y2 = 0;
- int w_ind = 0;
- int h_ind = 0; //
- for (int w = mStitch.W_min; w <= mStitch.W_max; w++)
- {
- for (int h = mStitch.H_min; h <= mStitch.Pheight; h++)
- {
- imsum = 0;//块差分集初始化
- x2 = 1;
- for (x1 = mStitch.Pwidth - w; x1 <= mStitch.Pwidth; x1 += 5)
- {
- y2 = 1;
- for (y1 = mStitch.Pheight - h + 1; y1 <= mStitch.Pheight; y1 += 5)
- {
- //块差分集计算
- CheckRC(ref x1, ref y1, mStitch.im);
- CheckRC(ref x2, ref y2, im2);
- imsum = imsum + Math.Abs(mStitch.im.At<Vec3b>(y1, x1).Item0 - im2.At<Vec3b>(y2, x2).Item0);
- y2 = y2 + 5;
- }
- x2 = x2 + 5;
- }
- //阈值更新
- if (imsum * 5 * 5 <= mStitch.minval * w * h)
- {
- mStitch.minval = imsum * 5 * 5 / (w * h);
- w_ind = w;
- h_ind = h;
- }
- }
- }
- imageParam.W_box = w_ind;
- imageParam.H_box = h_ind;
- imageParam.bdown = 1;
- //在下窗口所有匹配块内进行搜索
- Parallel.For(mStitch.W_min, mStitch.W_max, w =>
- {
- Parallel.For(mStitch.H_min, mStitch.Pheight, h =>
- {
- imsum = 0;//块差分集初始化
- x2 = 1;
- for (x1 = mStitch.Pwidth - w; x1 <= mStitch.Pwidth; x1 += 5)
- {
- y1 = 1;
- for (y2 = mStitch.Pheight - h + 1; y2 <= mStitch.Pheight; y2 += 5)
- {
- //块差分集计算
- CheckRC(ref x1, ref y1, mStitch.im);
- CheckRC(ref x2, ref y2, im2);
- imsum = imsum + Math.Abs(mStitch.im.At<Vec3b>(y1, x1).Item0 - im2.At<Vec3b>(y2, x2).Item0);
- y1 = y1 + 5;
- }
- x2 = x2 + 5;
- }
- //阈值更新
- if (imsum * 5 * 5 <= mStitch.minval * w * h)
- {
- mStitch.minval = imsum * 5 * 5 / (w * h);
- w_ind = w;
- h_ind = h;
- imageParam.bdown = 0;
- }
- });
- });
- imageParam.mStitch = mStitch;
- return imageParam;
- }
- public static void CheckRC(ref int x, ref int y, Mat im)
- {
- //图像矩阵访问有效性检测
- // 输入参数:
- // x——列
- // y——行
- // im——图像矩阵
- // 输出参数:
- // x——列
- // y——行
- y = Math.Max(y, 1);
- y = Math.Min(y, im.Height - 1);
- x = Math.Max(x, 1);
- x = Math.Min(x, im.Width - 1);
- }
- public Mat Fun_Stitch(ImageParam imageParam)
- {
- //图像融合
- //输入参数:
- //im2——待融合图像
- //W_box——宽度信息
- //H_box——高度信息
- //bdown——上下信息
- //MStitch——参数结构
- //输出参数:
- //MStitch——参数结构
- //im——融合图像
- Mat img = imageParam.im;
- int x1 = 0;
- int y1 = 0;
- int x2 = 0;
- int y2 = 0;
- double w = 0.5; //融合权值
- if (imageParam.bdown == 1)
- {
- //下区域重叠
- x2 = 1;
- //融合重叠区域
- for (x1 = imageParam.mStitch.Pwidth - imageParam.W_box; x1 < imageParam.mStitch.Pwidth; x1++)
- {
- y2 = 1;
- for (y1 = imageParam.mStitch.Pheight - imageParam.H_box + 1; y1 < imageParam.mStitch.Pheight; y1++)
- {
- //安全性检测
- CheckRC(ref x1, ref y1, imageParam.mStitch.im);
- CheckRC(ref x2, ref y2, imageParam.im);
- //融合权值
- w = (double)x2 / (double)imageParam.W_box;
- //加权融合
- double ColorRGB = imageParam.mStitch.im.At<Vec3b>(y1, x1).Item0 * (1.0 - w) + imageParam.im.At<Vec3b>(y2, x2).Item0 * w;
- imageParam.mStitch.im.Set<Vec3b>(y1, x1, new Vec3b((byte)ColorRGB, (byte)ColorRGB, (byte)ColorRGB));
- y2 = y2 + 1;
- }
- x2 = x2 + 1;
- }
- }
- else
- {
- //上区域重叠
- x2 = 1;
- //融合重叠区域
- for (x1 = imageParam.mStitch.Pwidth - imageParam.W_box; x1 < imageParam.mStitch.Pwidth; x1++)
- {
- y2 = 1;
- for (y1 = imageParam.mStitch.Pheight - imageParam.H_box + 1; y1 < imageParam.mStitch.Pheight; y1++)
- {
- //安全性检测
- CheckRC(ref x1, ref y1, imageParam.mStitch.im);
- CheckRC(ref x2, ref y2, imageParam.im);
- //融合权值
- w = (double)x2 / (double)imageParam.W_box;
- //加权融合
- double ColorRGB = imageParam.mStitch.im.At<Vec3b>(y1, x1).Item0 * (1.0 - w) + imageParam.im.At<Vec3b>(y2, x2).Item0 * w;
- imageParam.mStitch.im.Set<Vec3b>(y1, x1, new Vec3b((byte)ColorRGB, (byte)ColorRGB, (byte)ColorRGB));
- y2 = y2 + 1;
- }
- x2 = x2 + 1;
- }
- }
- //最终图
- img = new Mat(imageParam.mStitch.Pheight, imageParam.mStitch.Pwidth + imageParam.im.Width - x2 + 1, MatType.CV_8UC3);
- //分离出重叠区域
- OpenCvSharp.Rect m_select = new OpenCvSharp.Rect(x2 - 1, 0, imageParam.im.Width - x2 + 1, imageParam.mStitch.Pheight);
- Mat imgSwitch = new Mat(imageParam.im, m_select);
- Cv2.HConcat(imageParam.mStitch.im, imgSwitch, img);
- return img;
- }
- public Mat Fun_StitchRGB(ImageParam imageParam)
- {
- //图像融合
- //输入参数:
- //im2——待融合图像
- //W_box——宽度信息
- //H_box——高度信息
- //bdown——上下信息
- //MStitch——参数结构
- //输出参数:
- //MStitch——参数结构
- //im——融合图像
- Mat img = imageParam.im;
- int x1 = 0;
- int y1 = 0;
- int x2 = 0;
- int y2 = 0;
- double w = 0.5; //融合权值
- if (imageParam.bdown == 1)
- {
- //下区域重叠
- x2 = 1;
- //融合重叠区域
- for (x1 = imageParam.mStitch.Pwidth - imageParam.W_box; x1 < imageParam.mStitch.Pwidth; x1++)
- {
- y2 = 1;
- for (y1 = imageParam.mStitch.Pheight - imageParam.H_box + 1; y1 < imageParam.mStitch.Pheight; y1++)
- {
- //安全性检测
- CheckRC(ref x1, ref y1, imageParam.mStitch.im);
- CheckRC(ref x2, ref y2, imageParam.im);
- //融合权值
- w = (double)x2 / (double)imageParam.W_box;
- //加权融合
- double ColorR = imageParam.mStitch.im.At<Vec3b>(y1, x1).Item0 * (1.0 - w) + imageParam.im.At<Vec3b>(y2, x2).Item0 * w;
- double ColorG = imageParam.mStitch.im.At<Vec3b>(y1, x1).Item1 * (1.0 - w) + imageParam.im.At<Vec3b>(y2, x2).Item1 * w;
- double ColorB = imageParam.mStitch.im.At<Vec3b>(y1, x1).Item2 * (1.0 - w) + imageParam.im.At<Vec3b>(y2, x2).Item2 * w;
- if (imageParam.mStitch.im.At<Vec3b>(y1, x1).Item0 == imageParam.mStitch.im.At<Vec3b>(y1, x1).Item1 &&
- imageParam.mStitch.im.At<Vec3b>(y1, x1).Item1 == imageParam.mStitch.im.At<Vec3b>(y1, x1).Item2 &&
- imageParam.im.At<Vec3b>(y2, x2).Item0 == imageParam.im.At<Vec3b>(y2, x2).Item1 &&
- imageParam.im.At<Vec3b>(y2, x2).Item1 == imageParam.im.At<Vec3b>(y2, x2).Item2)
- {
- imageParam.mStitch.im.Set<Vec3b>(y1, x1, new Vec3b((byte)ColorR, (byte)ColorG, (byte)ColorB));
- }
- else
- {
- }
- y2 = y2 + 1;
- }
- x2 = x2 + 1;
- }
- }
- else
- {
- //上区域重叠
- x2 = 1;
- //融合重叠区域
- for (x1 = imageParam.mStitch.Pwidth - imageParam.W_box; x1 < imageParam.mStitch.Pwidth; x1++)
- {
- y2 = 1;
- for (y1 = imageParam.mStitch.Pheight - imageParam.H_box + 1; y1 < imageParam.mStitch.Pheight; y1++)
- {
- //安全性检测
- CheckRC(ref x1, ref y1, imageParam.mStitch.im);
- CheckRC(ref x2, ref y2, imageParam.im);
- //融合权值
- w = (double)x2 / (double)imageParam.W_box;
- //加权融合
- double ColorR = imageParam.mStitch.im.At<Vec3b>(y1, x1).Item0 * (1.0 - w) + imageParam.im.At<Vec3b>(y2, x2).Item0 * w;
- double ColorG = imageParam.mStitch.im.At<Vec3b>(y1, x1).Item1 * (1.0 - w) + imageParam.im.At<Vec3b>(y2, x2).Item1 * w;
- double ColorB = imageParam.mStitch.im.At<Vec3b>(y1, x1).Item2 * (1.0 - w) + imageParam.im.At<Vec3b>(y2, x2).Item2 * w;
- if (imageParam.mStitch.im.At<Vec3b>(y1, x1).Item0 == imageParam.mStitch.im.At<Vec3b>(y1, x1).Item1 &&
- imageParam.mStitch.im.At<Vec3b>(y1, x1).Item1 == imageParam.mStitch.im.At<Vec3b>(y1, x1).Item2 &&
- imageParam.im.At<Vec3b>(y2, x2).Item0 == imageParam.im.At<Vec3b>(y2, x2).Item1 &&
- imageParam.im.At<Vec3b>(y2, x2).Item1 == imageParam.im.At<Vec3b>(y2, x2).Item2)
- {
- imageParam.mStitch.im.Set<Vec3b>(y1, x1, new Vec3b((byte)ColorR, (byte)ColorG, (byte)ColorB));
- }
- else
- {
- }
- y2 = y2 + 1;
- }
- x2 = x2 + 1;
- }
- }
- //最终图
- img = new Mat(imageParam.mStitch.Pheight, imageParam.mStitch.Pwidth + imageParam.im.Width - x2 + 1, MatType.CV_8UC3);
- //分离出重叠区域
- OpenCvSharp.Rect m_select = new OpenCvSharp.Rect(x2 - 1, 0, imageParam.im.Width - x2 + 1, imageParam.mStitch.Pheight);
- Mat imgSwitch = new Mat(imageParam.im, m_select);
- Cv2.HConcat(imageParam.mStitch.im, imgSwitch, img);
- return img;
- }
- #endregion
- }
- }
|