ImageTools.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. using System;
  2. using System.Collections.Generic;
  3. using Emgu.CV;
  4. using Emgu.CV.CvEnum;
  5. using Emgu.CV.Structure;
  6. using Emgu.CV.Util;
  7. using System.Drawing;
  8. using WingServerCommon.Log;
  9. namespace WingAIDiagnosisService.Carotid.Utilities
  10. {
  11. /// <summary>
  12. /// 图像相关静态函数
  13. /// </summary>
  14. public class ImageTools
  15. {
  16. /// <summary>
  17. /// 调整图像亮度和对比度
  18. /// </summary>
  19. /// <param name="imageMat"></param>
  20. public static void Adjust(Mat imageMat)
  21. {
  22. var contrastDegree = 1.4;
  23. var brightness = 20;
  24. var sharpFactor = 1f;
  25. imageMat.ConvertTo(imageMat, Emgu.CV.CvEnum.DepthType.Cv8U, contrastDegree, brightness);
  26. //float[,] temp =
  27. // {{0, -sharpFactor, 0}, {-sharpFactor, 1 + 4 * sharpFactor, -sharpFactor}, {0, -sharpFactor, 0}};
  28. //ConvolutionKernelF kernel = new ConvolutionKernelF(temp);
  29. //CvInvoke.Filter2D(imageMat, imageMat, kernel, new Point(-1, -1));
  30. }
  31. /// <summary>
  32. /// 获取图像分割阈值
  33. /// </summary>
  34. /// <param name="image"></param>
  35. /// <returns></returns>
  36. public static int GetThreshold(CvArray<byte> image)
  37. {
  38. try
  39. {
  40. //统计每个灰度值的个数
  41. var grayValue = new int[256];
  42. var data = image.Bytes;
  43. foreach (var pixelValue in data)
  44. {
  45. grayValue[pixelValue]++;
  46. }
  47. //双峰法获取阈值------------------------
  48. var maxTemp = 0;
  49. var minTemp = 0;
  50. var sumMaxValue = 0;
  51. var sumMinValue = 0;
  52. var maxByte = 0;
  53. for (var i = grayValue.Length - 1; i > 1; --i)
  54. {
  55. if (grayValue[i] == 0) continue;
  56. maxByte = i;
  57. break;
  58. }
  59. if (maxByte == 0)
  60. {
  61. return 0;
  62. }
  63. var threshold = (1 + maxByte) / 2;
  64. int threshold1;
  65. int threshold2;
  66. do
  67. {
  68. for (var i = 0; i < 256; ++i)
  69. {
  70. var temp = grayValue[i];
  71. if (i > threshold)
  72. {
  73. maxTemp += temp;
  74. sumMaxValue += temp * i;
  75. }
  76. else
  77. {
  78. minTemp += temp;
  79. sumMinValue += temp * i;
  80. }
  81. }
  82. if (minTemp == 0)
  83. {
  84. return threshold;
  85. }
  86. if (maxTemp == 0)
  87. {
  88. return threshold;
  89. }
  90. threshold1 = (sumMaxValue / maxTemp + sumMinValue / minTemp) / 2;
  91. threshold2 = threshold;
  92. threshold = threshold1;
  93. } while (Math.Abs(threshold2 - threshold1) > 10);
  94. return threshold;
  95. }
  96. catch (Exception e)
  97. {
  98. Logger.WriteLineInfo("ImageTools GetThreshold," + e.Message + "," + e.StackTrace);
  99. return 0;
  100. }
  101. }
  102. /// <summary>
  103. /// 按照一列一列的方式去改变图像的像素
  104. /// </summary>
  105. /// <param name="image"></param>
  106. /// <param name="points"></param>
  107. /// <param name="rect"></param>
  108. public static void ChangeImageW(Image<Gray, byte> image, Point[] points, Rectangle rect)
  109. {
  110. var wMax = rect.Left + rect.Width;
  111. for (var w = rect.Left; w < wMax; w++)
  112. {
  113. var maxH = 0;
  114. var minH = int.MaxValue;
  115. foreach (var point in points)
  116. {
  117. if (point.X == w)
  118. {
  119. var y = point.Y;
  120. if (y > maxH)
  121. {
  122. maxH = y;
  123. }
  124. if (y < minH)
  125. {
  126. minH = y;
  127. }
  128. }
  129. }
  130. if (maxH <= 0) continue;
  131. for (var h = minH; h <= maxH; h++)
  132. {
  133. image.Data[h, w, 0] = 0;
  134. }
  135. }
  136. }
  137. /// <summary>
  138. /// 按照一行一行的方式去改变图像的像素
  139. /// </summary>
  140. /// <param name="image"></param>
  141. /// <param name="points"></param>
  142. /// <param name="rect"></param>
  143. public static void ChangeImageH(Image<Gray, byte> image, Point[] points, Rectangle rect)
  144. {
  145. var hMax = rect.Top + rect.Height;
  146. for (var h = rect.Top; h < hMax; h++)
  147. {
  148. var maxW = 0;
  149. var minW = int.MaxValue;
  150. foreach (var point in points)
  151. {
  152. if (point.Y == h)
  153. {
  154. var x = point.X;
  155. if (maxW < x)
  156. {
  157. maxW = x;
  158. }
  159. if (minW > x)
  160. {
  161. minW = x;
  162. }
  163. }
  164. }
  165. if (maxW > 0)
  166. {
  167. for (var w = minW; w <= maxW; w++)
  168. {
  169. image.Data[h, w, 0] = 0;
  170. }
  171. }
  172. }
  173. }
  174. /// <summary>
  175. /// 求两个点间的中间点
  176. /// </summary>
  177. /// <param name="p1">为开始点</param>
  178. /// <param name="p2">为结束点</param>
  179. /// <returns></returns>
  180. public static List<Point> GetPointsInTwoPoint(Point p1, Point p2)
  181. {
  182. try
  183. {
  184. if (p1 == p2)
  185. {
  186. return new List<Point>();
  187. }
  188. var x1 = p1.X;
  189. var y1 = p1.Y;
  190. var x2 = p2.X;
  191. var y2 = p2.Y;
  192. var x3 = x1 + Math.Abs(x2 - x1);
  193. var y3 = y1 + Math.Abs(y2 - y1);
  194. var pointList = new List<Point>();
  195. if (x1 == x3)
  196. {
  197. if (y3 - y1 == 1)
  198. {
  199. return new List<Point>();
  200. }
  201. for (var i = y1 + 1; i < y3; ++i)
  202. {
  203. pointList.Add(new Point(x1, i));
  204. }
  205. }
  206. if (y1 == y3)
  207. {
  208. if (x3 - x1 == 1)
  209. {
  210. return new List<Point>();
  211. }
  212. for (var i = x1 + 1; i < x3; ++i)
  213. {
  214. pointList.Add(new Point(i, y1));
  215. }
  216. }
  217. if (x3 - x1 == 1 && y3 - y1 == 1)
  218. {
  219. return new List<Point>();
  220. }
  221. var diffX = x3 - x1;
  222. var diffY = y3 - y1;
  223. var minDiff = Math.Min(diffX, diffY);
  224. for (var i = 1; i < minDiff; ++i)
  225. {
  226. pointList.Add(new Point(x1 + i, y1 + i));
  227. }
  228. if (diffX > diffY)
  229. {
  230. for (var i = x1 + minDiff; i < x3; ++i)
  231. {
  232. pointList.Add(new Point(i, y1 + minDiff));
  233. }
  234. }
  235. if (diffX < diffY)
  236. {
  237. for (var i = y1 + minDiff; i < y3; ++i)
  238. {
  239. pointList.Add(new Point(x1 + minDiff, i));
  240. }
  241. }
  242. //判断点的符号
  243. if (x2 > x1 && y2 > y1)
  244. {
  245. return pointList;
  246. }
  247. if (x2 > x1 && y2 < y1)
  248. {
  249. for (var i = 0; i < pointList.Count; ++i)
  250. {
  251. pointList[i] = new Point(pointList[i].X, 2 * y1 - pointList[i].Y);
  252. }
  253. }
  254. if (x2 < x1 && y2 > y1)
  255. {
  256. for (var i = 0; i < pointList.Count; ++i)
  257. {
  258. pointList[i] = new Point(2 * x1 - pointList[i].X, pointList[i].Y);
  259. }
  260. }
  261. if (x2 < x1 && y2 < y1)
  262. {
  263. for (var i = 0; i < pointList.Count; ++i)
  264. {
  265. pointList[i] = new Point(2 * x1 - pointList[i].X, 2 * y1 - pointList[i].Y);
  266. }
  267. }
  268. return pointList;
  269. }
  270. catch (Exception e)
  271. {
  272. Logger.WriteLineError("ImageTools GetPointsInTwoPoint error." + e.Message + "," + e.StackTrace);
  273. return new List<Point>();
  274. }
  275. }
  276. public static VectorOfVectorOfPoint FindContours(Image<Gray, byte> image)
  277. {
  278. var contours = new VectorOfVectorOfPoint();
  279. var outPutArray = new Mat();
  280. CvInvoke.FindContours(image, contours, outPutArray, RetrType.Ccomp, ChainApproxMethod.ChainApproxNone);
  281. return contours;
  282. }
  283. }
  284. }