OLDcellsegm.cs 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using OpenCvSharp;
  9. using Point = System.Drawing.Point;
  10. using Size = OpenCvSharp.Size;
  11. using ZhaoKThinAndConnectionDLL;
  12. namespace PaintDotNet.DedicatedAnalysis.GrainSizeStandard.IntegrationClass
  13. {
  14. internal class InParameter
  15. {
  16. public Mat MGryImg;
  17. public Mat MHesOutImage;
  18. public Mat MValley;
  19. public int iDimA;
  20. public int iDimB;
  21. }
  22. public class NewSeg
  23. {
  24. private Mat m_MOrgImg;
  25. private Mat m_MOutImg;
  26. private double[] m_adOutParam;
  27. private InParameter m_InParam;
  28. public int DoSeg(Mat _MOrgImg, Mat _MOutImg, double[] _adOutParam, Vec4b value)
  29. {
  30. PrepareParameter();
  31. m_MOrgImg = _MOrgImg;
  32. m_MOutImg = _MOutImg;
  33. m_adOutParam = _adOutParam;
  34. if (3 == m_MOrgImg.Channels())
  35. {
  36. Cv2.CvtColor(m_MOrgImg, m_InParam.MGryImg, ColorConversionCodes.RGB2GRAY);
  37. }
  38. else
  39. {
  40. if (1 != m_MOrgImg.Channels())
  41. {
  42. return -1;
  43. }
  44. m_InParam.MGryImg = m_MOrgImg.Clone();
  45. }
  46. ImgHessian();
  47. FindValley();
  48. FindShed(value);
  49. return 1;
  50. }
  51. private int FindShed(Vec4b value)
  52. {
  53. Mat mat = new Mat(m_InParam.MValley.Size(), 4);
  54. Cv2.FindContours(m_InParam.MValley, out OpenCvSharp.Point[][] contours, out HierarchyIndex[] hierarchy, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple);
  55. for (int i = 0; i < hierarchy.Length; i++)
  56. {
  57. Cv2.DrawContours(mat, contours, i, Scalar.All(i + 1), 1, LineTypes.Link8, hierarchy);
  58. }
  59. Cv2.Watershed(m_MOrgImg, mat);
  60. int rows = mat.Rows;
  61. int cols = mat.Cols;
  62. int[] array = new int[2];
  63. //Vec3b value = new Vec3b(0, 0, byte.MaxValue);
  64. array[0] = 0;
  65. while (array[0] < rows)
  66. {
  67. array[1] = 0;
  68. while (array[1] < cols)
  69. {
  70. if (0 >= mat.At<int>(array[0], array[1]))
  71. {
  72. m_MOutImg.Set(array, value);
  73. }
  74. array[1]++;
  75. }
  76. array[0]++;
  77. }
  78. return 1;
  79. }
  80. private int FindValley()
  81. {
  82. Mat structuringElement = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(m_InParam.iDimA, m_InParam.iDimA), new OpenCvSharp.Point(-1, -1));
  83. Cv2.MorphologyEx(m_InParam.MHesOutImage, m_InParam.MHesOutImage, MorphTypes.Close, (InputArray)structuringElement);
  84. Cv2.BitwiseNot(m_InParam.MHesOutImage, m_InParam.MValley);
  85. Size size = m_InParam.MValley.Size();
  86. Mat mat = (Mat)Mat.Zeros(size.Height + 2, size.Width + 2, m_InParam.MValley.Type());
  87. m_InParam.MValley.CopyTo(mat.SubMat(new Range(1, size.Height + 1), new Range(1, size.Width + 1)));
  88. Cv2.FloodFill(mat, new OpenCvSharp.Point(0, 0), new Scalar(255.0));
  89. Mat mat2 = new Mat();
  90. mat.SubMat(new Range(1, size.Height + 1), new Range(1, size.Width + 1)).CopyTo(mat2);
  91. Cv2.BitwiseNot(mat2, mat2);
  92. m_InParam.MValley = (Mat)(m_InParam.MValley | mat2);
  93. return 1;
  94. }
  95. private int PrepareParameter()
  96. {
  97. m_InParam = new InParameter();
  98. m_InParam.MGryImg = new Mat();
  99. m_InParam.MHesOutImage = new Mat();
  100. m_InParam.MValley = new Mat();
  101. m_InParam.iDimA = 3;
  102. m_InParam.iDimB = 1;
  103. return 1;
  104. }
  105. private int ImgHessian()
  106. {
  107. Mat mat = new Mat();
  108. m_InParam.MGryImg.ConvertTo(mat, 5);
  109. int rows = mat.Rows;
  110. int cols = mat.Cols;
  111. int num = 5;
  112. double num2 = 1.2;
  113. Mat mat2 = new Mat(2 * num + 1, 2 * num + 1, MatType.CV_32FC1, Scalar.All(0.0));
  114. Mat mat3 = new Mat(2 * num + 1, 2 * num + 1, MatType.CV_32FC1, Scalar.All(0.0));
  115. Mat mat4 = new Mat(2 * num + 1, 2 * num + 1, MatType.CV_32FC1, Scalar.All(0.0));
  116. for (int i = -num; i <= num; i++)
  117. {
  118. for (int j = -num; j <= num; j++)
  119. {
  120. double num3 = 1.0 - (double)(i * i) / (num2 * num2);
  121. double num4 = Math.Exp((double)(-1 * (i * i + j * j)) / (2.0 * num2 * num2));
  122. double num5 = -1.0 / (Math.PI * 2.0 * Math.Pow(num2, 4.0));
  123. double num6 = num3 * num4 * num5;
  124. float value = (float)num6;
  125. mat2.Set(i + num, j + num, value);
  126. mat4.Set(i + num, j + num, (float)((1.0 - (double)(j * j) / (num2 * num2)) * Math.Exp((double)(-1 * (i * i + j * j)) / (2.0 * num2 * num2)) * (-1.0 / (Math.PI * 2.0 * Math.Pow(num2, 4.0)))));
  127. mat3.Set(i + num, j + num, (float)((double)(i * j) * Math.Exp((double)(-1 * (i * i + j * j)) / (2.0 * num2 * num2)) * (1.0 / (Math.PI * 2.0 * Math.Pow(num2, 6.0)))));
  128. }
  129. }
  130. Mat mat5 = new Mat(rows, cols, MatType.CV_32FC1, Scalar.All(0.0));
  131. Mat mat6 = new Mat(rows, cols, MatType.CV_32FC1, Scalar.All(0.0));
  132. Mat mat7 = new Mat(rows, cols, MatType.CV_32FC1, Scalar.All(0.0));
  133. Cv2.Filter2D(mat, mat5, mat5.Depth(), mat2);
  134. Cv2.Filter2D(mat, mat6, mat6.Depth(), mat4);
  135. Cv2.Filter2D(mat, mat7, mat7.Depth(), mat3);
  136. byte[,] array = new byte[rows, cols];
  137. float[] array2 = new float[rows * cols];
  138. float[] array3 = new float[rows * cols];
  139. float[] array4 = new float[rows * cols];
  140. Marshal.Copy(mat5.Data, array2, 0, rows * cols);
  141. Marshal.Copy(mat6.Data, array3, 0, rows * cols);
  142. Marshal.Copy(mat7.Data, array4, 0, rows * cols);
  143. for (int k = 0; k < rows; k++)
  144. {
  145. for (int l = 0; l < cols; l++)
  146. {
  147. float num7 = array2[k * cols + l];
  148. float num8 = array3[k * cols + l];
  149. float num9 = array4[k * cols + l];
  150. double num10 = (num7 + num8) * (num7 + num8) - 4f * (num7 * num8 - num9 * num9);
  151. if (!(num10 < 0.0))
  152. {
  153. num10 = Math.Sqrt(num10);
  154. double num11 = ((double)(num7 + num8) + num10) / 2.0;
  155. double value2 = ((double)(num7 + num8) - num10) / 2.0;
  156. if (num11 > 0.0 && Math.Abs(num11) > 1.0 + Math.Abs(value2))
  157. {
  158. array[k, l] = byte.MaxValue;
  159. }
  160. }
  161. }
  162. }
  163. m_InParam.MHesOutImage = new Mat(rows, cols, MatType.CV_8UC1, array, 0L);
  164. return 0;
  165. }
  166. }
  167. /////
  168. /////
  169. class OUTsegmsurf
  170. {
  171. public Mat cellbw;
  172. public Mat wat;
  173. public Mat imsegm;
  174. public Mat minima;
  175. public Mat minimacell;
  176. //kkkkk public NEW_TYPE_SegInf info;
  177. }
  178. class In5segmsurf
  179. {
  180. public string smoothim_method;
  181. public int filterridges;
  182. public double gaussian_stdev;
  183. public string LEVEL;
  184. public double classifycells_convexarea;
  185. public double classifycells_convexperim;
  186. public Mat OrgImg;
  187. public In5segmsurf Clone()
  188. {
  189. return this.MemberwiseClone() as In5segmsurf;
  190. }
  191. }
  192. class In6segmsurf
  193. {
  194. public string prmfile;//Path to parameter file
  195. public Mat minima;//All markers, for instance from manual drawings
  196. public Mat minimacell;//; for cells, for instance from manual drawings
  197. public Mat imnucl;//Nucleus image for defining markers
  198. }
  199. class PMergefragments//区域合并
  200. {
  201. public int optlog;
  202. public int optint;
  203. public double intint;
  204. public double conv;
  205. public PMergefragments Clone()
  206. {
  207. return this.MemberwiseClone() as PMergefragments;
  208. }
  209. }
  210. class PSmoothim//平滑
  211. {
  212. public string method;
  213. public double[] h;
  214. public int gpu;
  215. public int dim;
  216. public int ced_maxniter;
  217. public PSmoothim Clone()
  218. {
  219. return this.MemberwiseClone() as PSmoothim;
  220. }
  221. }
  222. class PClassifycells//区域分类
  223. {
  224. public double convexarea;
  225. public double convexperim;
  226. public double[] h;
  227. public double minvolfull;
  228. public double maxvolfull;
  229. public string method;
  230. public PClassifycells Clone()
  231. {
  232. return this.MemberwiseClone() as PClassifycells;
  233. }
  234. }
  235. class In4smoothim
  236. {
  237. public int filterridges;
  238. public string LEVEL;
  239. public double gaussian_stdev;
  240. public double[] getminima_h;
  241. public double getminima_minvolfull;
  242. public double getminima_maxvolfull;
  243. public double getminima_level;
  244. //public string getminima_method;
  245. public PMergefragments mergefragments;
  246. public PSmoothim smoothim;
  247. public PClassifycells classifycells;
  248. public int[] dim;
  249. public double minvol;
  250. public double minvolvox;
  251. public double maxvol;
  252. public double maxvolvox;
  253. public double watminvolfull;
  254. public double watmaxvolfull;
  255. public double minvolfull;
  256. public double maxvolfull;
  257. public double[] h;
  258. public double just;
  259. public int gpu;
  260. public int illum;
  261. public double illumdiameter;
  262. public int merge;
  263. public int iInterpolationMethod;//zzzzz new, 1 for Cubic spline interpolation, 2 for Bilinear interpolation, 3 for Nearest neighbor interpolation
  264. }
  265. class OUTgetminima
  266. {
  267. public Mat minimacell;
  268. public Mat minima;
  269. }
  270. class OUTclassifycells
  271. {
  272. public Mat cellbw;
  273. public PClassifycells classifycells;
  274. }
  275. class OUTmaxfilt3
  276. {
  277. public List<float>[,] maxim;
  278. public float[,] sumim;
  279. public int numpoints;
  280. public float[][][] minim;
  281. }
  282. class MyFilter
  283. {
  284. public double[] x;
  285. public double[] y;
  286. public double[] z;
  287. }
  288. class OLDcellsegm
  289. {
  290. public const double m_PI = 3.1415926535897931;
  291. void mf_mergeinputpar(In4smoothim prm, In5segmsurf prmin)
  292. {
  293. prm.smoothim.method = prmin.smoothim_method;
  294. prm.filterridges = prmin.filterridges;
  295. prm.gaussian_stdev = prmin.gaussian_stdev;
  296. prm.LEVEL = (string)prmin.LEVEL.Clone();
  297. prm.classifycells.convexarea = prmin.classifycells_convexarea;
  298. prm.classifycells.convexperim = prmin.classifycells_convexperim;
  299. }
  300. void mf_cellsize(double minvol, double maxvol, In4smoothim prm, int ThreeDimNO)
  301. {
  302. if (0 == prm.h[0] * prm.h[1] * prm.h[2])
  303. {
  304. Console.WriteLine("There is zero voxel size");
  305. }
  306. double minr = Math.Pow((3 * minvol) / (4 * m_PI), 1 / 3);
  307. //maxr = ((3*maxvol)/(4*pi))^(1/3);
  308. //maxz = maxr/h(3);
  309. double minz = minr / prm.h[2];
  310. if (ThreeDimNO < minz)
  311. {
  312. //shrinink a sphere to a circle
  313. double r = Math.Pow((3 * maxvol) / (4 * m_PI), 1 / 3);
  314. maxvol = Math.Pow(ThreeDimNO, prm.just) * m_PI * r * r;
  315. r = Math.Pow((3 * minvol) / (4 * m_PI), 1 / 3);
  316. minvol = Math.Pow(ThreeDimNO, prm.just) * m_PI * r * r;
  317. }
  318. double voxelvol = prm.h[0] * prm.h[1] * prm.h[2];
  319. double minvolvox = Math.Round(minvol / voxelvol, MidpointRounding.AwayFromZero);
  320. double maxvolvox = Math.Round(maxvol / voxelvol, MidpointRounding.AwayFromZero);
  321. prm.minvol = minvol;
  322. prm.minvolvox = minvolvox;
  323. prm.maxvol = maxvol;
  324. prm.maxvolvox = maxvolvox;
  325. }
  326. public OUTsegmsurf mf_segmsurf_progress_auto(Mat GryImg, double minvol, double maxvol,
  327. string[] INnamehere, In5segmsurf IN5varhere, In6segmsurf IN6varhere, Color phaseColor)
  328. {
  329. long start = Cv2.GetTickCount();
  330. OUTsegmsurf rtn = new OUTsegmsurf();
  331. //ttttt Cv2.FindContours(watermark, out contour, out hier, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple, null);
  332. rtn.wat = new Mat(GryImg.Size(), MatType.CV_8UC4, new Scalar(255, 0, 0, 0));
  333. //Mat OutImg = new Mat(GryImg.Rows, GryImg.Cols, MatType.CV_8UC3, Scalar.All(0));
  334. NewSeg NSeg = new NewSeg();
  335. //转为为灰度?
  336. if (/*3 == GryImg.Channels() || */4 == GryImg.Channels())
  337. {
  338. Cv2.CvtColor(GryImg, GryImg, ColorConversionCodes.BGRA2BGR);
  339. }
  340. else if (1 == GryImg.Channels())
  341. {
  342. Cv2.CvtColor(GryImg, GryImg, ColorConversionCodes.GRAY2BGR);
  343. }
  344. //Cv2.ImShow("oriImg", GryImg);
  345. //Cv2.WaitKey();
  346. double time_v2 = (Cv2.GetTickCount() - start) / Cv2.GetTickFrequency();
  347. System.Console.WriteLine("晶界重现_V2_执行时间1:" + time_v2);
  348. NSeg.DoSeg(GryImg.Clone()/*OrgImg*/, rtn.wat, null, new Vec4b(phaseColor.B, phaseColor.G, phaseColor.R, 255));
  349. ////ttttt Cv2.DrawContours(rtn.wat, contour, -1, Scalar.Red);
  350. //int Rows = OutImg.Rows;
  351. //int Cols = OutImg/*watermark*/.Cols;
  352. //int[] point = new int[2];
  353. //Vec4b redcol;
  354. //if (phaseColor != null)
  355. //{
  356. // redcol = new Vec4b(phaseColor.B, phaseColor.G, phaseColor.R, 255);
  357. //}
  358. //else
  359. // redcol = new Vec4b(0, 0, 255/*255*/, 255);
  360. //for (point[0] = 0; point[0] < Rows; point[0]++)
  361. //{
  362. // for (point[1] = 0; point[1] < Cols; point[1]++)
  363. // {
  364. // if (0 >= watermark.At<int>(point[0], point[1]))
  365. // {
  366. // rtn.wat.Set<Vec4b>(point[0], point[1], redcol);//###
  367. // }
  368. // }
  369. //}
  370. time_v2 = (Cv2.GetTickCount() - start) / Cv2.GetTickFrequency();
  371. System.Console.WriteLine("晶界重现_V2_执行时间2:" + time_v2);
  372. ////Cv2.ImShow("contour", rtn.wat);//kkkkk
  373. ////Cv2.WaitKey(0);//kkkkk
  374. //control.Cursor = cursor;// System.Windows.Forms.Cursors.Default;
  375. return rtn;
  376. //System.Windows.Forms.Cursor cursor = control.Cursor;//.GetHashCode();//.CopyHandle();
  377. //control.Cursor = System.Windows.Forms.Cursors.WaitCursor;
  378. string mfilename = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
  379. Console.WriteLine("This is" + mfilename + "for segmentation of cells");
  380. //image for segmentation
  381. Mat imsegm = GryImg.Clone();
  382. //cell volumes in cubic microns
  383. double minvolfull = 1000 * minvol;
  384. double maxvolfull = 1000 * maxvol;
  385. Mat imsegmini = imsegm.Clone();
  386. Mat minimacell = null;
  387. Mat minima = null;
  388. Mat imnucl = null;
  389. string prmfile = null;
  390. /*
  391. //for visualilzation
  392. int vis = 0;
  393. int visfinal = 0;
  394. */
  395. In4smoothim prm = new In4smoothim();
  396. prm.mergefragments = new PMergefragments();
  397. prm.smoothim = new PSmoothim();
  398. prm.classifycells = new PClassifycells();
  399. /*Standard parameters*/
  400. //voxel size
  401. prm.h = new double[3] { 0.5, 0.5, 1.5 };
  402. //adjust for not fully circular shape of 3D cells
  403. prm.just = 0.9;
  404. //filter ridges
  405. prm.filterridges = 0;
  406. //GPU, requires
  407. prm.gpu = 0;
  408. //correct illumination
  409. prm.illum = 0;
  410. prm.illumdiameter = 25;
  411. /*Minima parameters*/
  412. //level
  413. prm.getminima_level = 0.30;
  414. /*
  415. //method
  416. prm.getminima_method = "automated";
  417. */
  418. /*Smoothing parameters*/
  419. //directional coherence enhancing diffusion
  420. prm.smoothim.method = "dirced";
  421. //2D or 3D smoothing
  422. prm.smoothim.dim = 2;
  423. //number of iterations of smoothing in CED
  424. prm.smoothim.ced_maxniter = 100;
  425. //dimension image
  426. int[] dim = new int[3] { imsegm.Rows, imsegm.Cols, 1 };
  427. /*Classification parameters*/
  428. prm.classifycells.method = "threshold";
  429. /*Watershed parameters*/
  430. //To test intensity of wat lines; merging
  431. prm.merge = 0;
  432. //methods for merging
  433. prm.mergefragments.optlog = 2;
  434. prm.mergefragments.optint = 2;
  435. /* The signicance of watershed lines, stronger if larger, done on ridgeim!!
  436. if the raw image, then use much smaller, around 1
  437. set to 1.05-1.10
  438. prm.watthint = 1.06;*/
  439. prm.mergefragments.intint = 1.3;
  440. /* The conexity measure for the merging, we should not allow a very much
  441. smaller convexity after merging
  442. thconv = 1 if no change in convexity
  443. thconv > 1 if increase in convexity
  444. thconv < 1 if decrease in convexity */
  445. prm.mergefragments.conv = 1.0;
  446. if (maxvolfull < minvolfull)
  447. {
  448. Console.WriteLine(mfilename + ": The upper cell volume is lower than the lower, check the input");
  449. }
  450. /* 无用matlab代码
  451. % read from parameter file?
  452. for i = 4 : 2 : nargin
  453. namehere = varargin{4};
  454. varhere = varargin{5};
  455. switch(namehere)
  456. case('prmfile')
  457. prmfile = varhere;
  458. otherwise
  459. % nothing
  460. end;
  461. end;
  462. %
  463. % Load the parameter file if one is given
  464. %
  465. if ~isempty(prmfile)
  466. isfolder = ~isempty(strfind(prmfile,'/'));
  467. [a b c] = fileparts(prmfile);
  468. if isfolder
  469. A = pwd;
  470. cd(a);
  471. end;
  472. msg = sprintf('Reading from parameter file %s',prmfile);
  473. disp(msg);
  474. cmd = [b c];
  475. prmin = eval(cmd);
  476. if isfolder
  477. cd(A);
  478. end;
  479. % merge the structs by overriding the existing values
  480. prm = mergestruct(prm,prmin);
  481. end;
  482. */
  483. /*The command line has the highest priority, merge the variables here*/
  484. In5segmsurf prmin = null;
  485. for (int i = 0; i < INnamehere.GetLength(0); i++)
  486. {
  487. //this variable
  488. string namehere = INnamehere[i];
  489. switch (namehere)
  490. {
  491. case "minima":
  492. minima = IN6varhere.minima;
  493. break;
  494. case "prm":
  495. prmin = IN5varhere.Clone();
  496. mf_mergeinputpar(prm, prmin);
  497. break;
  498. case "minimacell":
  499. minimacell = IN6varhere.minimacell;
  500. break;
  501. case "imnucleus":
  502. imnucl = IN6varhere.imnucl;
  503. break;
  504. default:
  505. Console.WriteLine("Wrong option " + namehere);
  506. break;
  507. }
  508. }
  509. prm.dim = new int[2] { imsegm.Rows, imsegm.Cols };
  510. /* 无用matlab代码
  511. % if you give in a nucleus image you want to use it!
  512. if ~isempty(imnucl)
  513. prm.getminima.method = 'nucleus';
  514. prm.classifycells.method = 'minimacell';
  515. end;
  516. % test for credibility!
  517. if isequal(prm.getminima.method,'manual')
  518. if isempty(minima) && isempty(minimacell)
  519. error('You must specify either minima eller minimacell')
  520. end;
  521. end;
  522. if isequal(prm.getminima.method,'nucleus')
  523. if isempty(imnucl)
  524. error('You must specify a nucleus image');
  525. end;
  526. end;
  527. */
  528. /*Computed settings*/
  529. //get the ADJUSTED 3D cell size, in case its not a full 3D volume.
  530. //NB: This is not always linearly scalable, try to avoid using reduced 3D.
  531. mf_cellsize(minvolfull, maxvolfull, prm, dim[2]);
  532. //give the voxel sizes in thousand, since all programs are tuned for this
  533. //prm.classifycells.minvolfull = prm.classifycells.minvolfull;
  534. //prm.classifycells.maxvolfull = prm.classifycells.maxvolfull;
  535. prm.getminima_minvolfull = minvolfull / 1000;
  536. prm.getminima_maxvolfull = maxvolfull / 1000;
  537. prm.watminvolfull = minvolfull / 1000;
  538. prm.watmaxvolfull = maxvolfull / 1000;
  539. prm.minvolfull = minvolfull;
  540. prm.maxvolfull = maxvolfull;
  541. prm.classifycells.minvolfull = minvolfull / 1000;
  542. prm.classifycells.maxvolfull = maxvolfull / 1000;
  543. Console.WriteLine("Using settings:");
  544. /* 无用matlab代码
  545. printstructscreen(prm);
  546. */
  547. //pixel size
  548. prm.getminima_h = (double[])prm.h.Clone();
  549. prm.classifycells.h = (double[])prm.h.Clone();
  550. prm.smoothim.h = (double[])prm.h.Clone();
  551. //gpu for smoothing
  552. prm.smoothim.gpu = prm.gpu;
  553. //zzzzz
  554. prm.iInterpolationMethod = 1;
  555. /*Cell segmentation start*/
  556. //Correcting for uneven illumination
  557. //Smoothing
  558. PSmoothim prminsmt = prm.smoothim.Clone();
  559. imsegm = smoothim(imsegm, prm.smoothim.method, "prm", prm);
  560. //zzzzz Cv2.ImShow("smoothim", imsegm);//kkkkk
  561. //zzzzz Cv2.WaitKey(0);//kkkkk
  562. //Ridge enhancement
  563. if (1 == prm.filterridges)
  564. {
  565. Console.WriteLine("Ridge enhancement");
  566. //kkkkk imsegm = cellsegm.ridgeenhhessian(imsegm,prm.h);
  567. }
  568. else
  569. {
  570. Console.WriteLine("No ridge enhancement");
  571. }
  572. //Finding minima
  573. OUTgetminima gmout = getminima(imsegm, minimacell, prmin);
  574. //kkkkk minimacell = gmout.minimacell;
  575. minima = gmout.minima;
  576. //3D watershed segmentation
  577. Console.WriteLine("3D watershed segmentation");
  578. //Iimpose = imimposemin(imsegm,minima);
  579. //wat = watershed(Iimpose);
  580. //vector<vector<Point>> contour;
  581. Mat watermark = new Mat(imsegm.Size(), MatType.CV_32S);
  582. OpenCvSharp.Point[][] contour;
  583. HierarchyIndex[] hier;
  584. Cv2.FindContours(minima, out contour, out hier, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple, null);
  585. for (int i = 0; i < hier.Length; i++)
  586. {
  587. Cv2.DrawContours(watermark, contour, i, Scalar.All(i + 1), 1, LineTypes.Link8, hier);
  588. }
  589. //Mat Temp = new Mat(imsegm.Size(), MatType.CV_8UC3);
  590. //imsegm.CopyTo(Temp);
  591. Cv2.Watershed(IN5varhere.OrgImg, watermark);//mmmmm
  592. //Mat afterWatershed = new Mat();//kkkkk
  593. //Cv2.ConvertScaleAbs(watermark, afterWatershed);//kkkkk
  594. //Cv2.ImWrite("D:\\afterWatershed.jpg", afterWatershed);//kkkkk
  595. //Cv2.ImShow("watermark", afterWatershed);//kkkkk
  596. //Cv2.WaitKey(0);//kkkkk
  597. PClassifycells prmclf = prm.classifycells.Clone();
  598. OUTclassifycells cfout;
  599. if (null != minimacell)//mmmmm
  600. {
  601. cfout = classifycells(watermark, imsegmini, prmclf, minimacell);
  602. }
  603. else
  604. {
  605. cfout = classifycells(watermark, imsegmini, prmclf);
  606. }
  607. Mat cellbw = cfout.cellbw;
  608. //kkkkk info.classifycells = cfout.classifycells;
  609. //kkkkk info.prm = prm;
  610. //9. 绘制轮廓 drawContours
  611. //Mat maskers = Mat::zeros(imgDist8U.size(), CV_32SC1);
  612. //for (size_t i=0; i<contour.size(); i++){
  613. //drawContours(maskers, contour, static_cast<int>(i), Scalar::all(static_cast<int>(i) + 1)); }
  614. //imshow("maskers", maskers);
  615. //ttttt Cv2.FindContours(watermark, out contour, out hier, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple, null);
  616. rtn.wat = new Mat(watermark.Size(), MatType.CV_8UC4, new Scalar(255, 0, 0, 0));
  617. //ttttt Cv2.DrawContours(rtn.wat, contour, -1, Scalar.Red);
  618. int Rows = watermark.Rows;
  619. int Cols = watermark.Cols;
  620. int[] point = new int[2];
  621. Vec4b redcol;
  622. if (phaseColor != null)
  623. {
  624. redcol = new Vec4b(phaseColor.B, phaseColor.G, phaseColor.R, 255);
  625. }
  626. else
  627. redcol = new Vec4b(0, 0, 255/*255*/, 255);
  628. for (point[0] = 0; point[0] < Rows; point[0]++)
  629. {
  630. for (point[1] = 0; point[1] < Cols; point[1]++)
  631. {
  632. if (0 >= watermark.At<int>(point[0], point[1]))
  633. {
  634. rtn.wat.Set<Vec4b>(point[0], point[1], redcol);//###
  635. }
  636. }
  637. }
  638. double time = (Cv2.GetTickCount() - start) / Cv2.GetTickFrequency();
  639. System.Console.WriteLine("晶界重现_执行时间:" + time);
  640. ////Cv2.ImShow("contour", rtn.wat);//kkkkk
  641. ////Cv2.WaitKey(0);//kkkkk
  642. //control.Cursor = cursor;// System.Windows.Forms.Cursors.Default;
  643. return rtn;
  644. }
  645. OUTclassifycells classifycells(Mat watermark, Mat imsegmini, PClassifycells prmclf, Mat minimacell = null)
  646. {
  647. OUTclassifycells rtn = new OUTclassifycells();
  648. return rtn;
  649. }
  650. OUTgetminima getminima(Mat imsegm, Mat minimacell, In5segmsurf prmin)
  651. {
  652. OUTgetminima rtn = new OUTgetminima();
  653. rtn.minima = null;
  654. rtn.minimacell = null;
  655. if (null == minimacell)
  656. {
  657. rtn.minima = automated(imsegm, prmin);
  658. }
  659. return rtn;
  660. }
  661. Mat automated(Mat imsegm, In5segmsurf prmin)
  662. {
  663. Mat mat_mean = new Mat(), mat_stddev = new Mat();
  664. double m, s, d;
  665. //Cv2.MeanStdDev(imsegm, mat_mean, mat_stddev);
  666. //m = mat_mean.At<double>(0, 0);
  667. //s = mat_stddev.At<double>(0, 0);
  668. //d = 0;//mmmmm
  669. double th;
  670. //th = Math.Min(Math.Max(m+d*s, m/2),1.5*m);
  671. Mat minima = new Mat(), minimacell = new Mat(imsegm.Size(), MatType.CV_8UC3);
  672. //Cv2.Threshold(imsegm, minimacell, th, 255, ThresholdTypes.Binary);
  673. int iRad = 39;
  674. Mat matTempA = new Mat();
  675. Mat matTempB = new Mat();
  676. Cv2.MedianBlur(imsegm, matTempA, iRad);
  677. Cv2.AddWeighted(imsegm, 1, matTempA, -1, 0, matTempB);
  678. Cv2.MeanStdDev(matTempB, mat_mean, mat_stddev);
  679. m = mat_mean.At<double>(0, 0);
  680. s = mat_stddev.At<double>(0, 0);
  681. d = 0;//mmmmm
  682. th = m + d * s;
  683. Cv2.Threshold(matTempB, minimacell, th, 255, ThresholdTypes.Binary);
  684. int diam;//mmmmm
  685. Mat kernel;
  686. diam = 9;
  687. kernel = Cv2.GetStructuringElement(MorphShapes.Cross, new Size(diam, diam), new OpenCvSharp.Point(-1, -1));
  688. Cv2.Dilate(minimacell, minimacell, kernel);
  689. diam = 3;
  690. kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(diam, diam), new OpenCvSharp.Point(-1, -1));
  691. Cv2.Erode(minimacell, minimacell, kernel);
  692. Cv2.MorphologyEx(minimacell, minimacell, MorphTypes.Open, kernel);
  693. //zzzzz Cv2.ImShow("bianjie", minimacell);
  694. //zzzzz Cv2.WaitKey(0);
  695. Cv2.BitwiseNot(minimacell, minima);
  696. Size bianjieSize = minima.Size();
  697. Mat Temp = Mat.Zeros(bianjieSize.Height + 2, bianjieSize.Width + 2, minimacell.Type());//延展图像
  698. minima.CopyTo(Temp.SubMat(new Range(1, bianjieSize.Height + 1), new Range(1, bianjieSize.Width + 1)));
  699. Cv2.FloodFill(Temp, new OpenCvSharp.Point(0, 0), new Scalar(255));
  700. Mat cutImg = new Mat();
  701. Temp.SubMat(new Range(1, bianjieSize.Height + 1), new Range(1, bianjieSize.Width + 1)).CopyTo(cutImg);
  702. Cv2.BitwiseNot(cutImg, cutImg);
  703. minima = minima | cutImg;
  704. diam = 9;
  705. kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(diam, diam), new OpenCvSharp.Point(-1, -1));
  706. Cv2.MorphologyEx(minima, minima, MorphTypes.Open, kernel);
  707. //zzzzz Cv2.ImShow("neibu", minima);//kkkkk
  708. //zzzzz Cv2.WaitKey(0);//kkkkk
  709. return minima;
  710. }
  711. Mat smoothim(Mat im, string method, string prmflg, In4smoothim prm)
  712. {
  713. //diameter of filter
  714. int iPrmD = 13;
  715. Mat rst = new Mat();
  716. Cv2.ConvertScaleAbs(dircohenh(im, iPrmD, prm.h, prm.iInterpolationMethod), rst);
  717. return rst;
  718. }
  719. Mat dircohenh(Mat im, int iPrmD, double[] adPrmH, int iInterpolationMethod)
  720. {
  721. int[] dim = new int[3] { im.Rows, im.Cols, 1 };
  722. if (3 == im.Dims())
  723. {
  724. dim[2] = im.Height;
  725. }
  726. //number of elements to remove before one takes the Olympic average. Set to
  727. //1-->3
  728. int numremele = 2;
  729. int stepxy = 30;
  730. int numdeghere = (180 - stepxy) / stepxy + 1;
  731. int[] deghere = new int[numdeghere];
  732. deghere[0] = 0;
  733. for (int i = 1; i < numdeghere; i++)
  734. {
  735. deghere[i] = deghere[i - 1] + stepxy;
  736. }
  737. double[,] deg2D = new double[numdeghere, 2];
  738. for (int i = 1; i < numdeghere; i++)
  739. {
  740. deg2D[i, 0] = (double)(deghere[i]);
  741. deg2D[i, 1] = 90;
  742. }
  743. double[,] deg;
  744. deg = deg2D;
  745. if (1 != dim[2])
  746. {
  747. double[,] deg3D = new double[numdeghere + 1, 2];
  748. for (int i = 1; i < numdeghere; i++)
  749. {
  750. deg3D[i, 0] = deg2D[i, 0];
  751. deg3D[i, 1] = deg2D[i, 1];
  752. }
  753. deg3D[numdeghere, 0] = 0;
  754. deg3D[numdeghere, 1] = 0;
  755. deg = deg3D;
  756. }
  757. //the half filter size
  758. int p = iPrmD / 2;
  759. //make filter
  760. MyFilter[] c = makefilter(deg, p);
  761. //number of directions
  762. int numdir = c.Length;
  763. //inisization
  764. Mat filtim = new Mat(im.Rows, im.Cols, MatType.CV_32F, 0.0);
  765. //zzzzz
  766. //201118 for Acceleration Mat imRs = new Mat();
  767. Mat imRs = null;
  768. float[] afImRs = null;
  769. int iProportion = 5;
  770. if (1 == iInterpolationMethod)
  771. {
  772. imRs = new Mat();//201118 for Acceleration
  773. Mat imFt = new Mat();
  774. im.ConvertTo(imFt, MatType.CV_32F);
  775. Cv2.Resize(imFt, imRs, new Size(imFt.Cols * iProportion, imFt.Rows * iProportion), 0, 0, InterpolationFlags.Cubic);
  776. //afImRs = new float[imRs.Rows, imRs.Cols];
  777. afImRs = new float[imRs.Rows * imRs.Cols];
  778. Marshal.Copy(imRs.Data, afImRs, 0, imRs.Rows * imRs.Cols);
  779. /*
  780. for (int i = 0; i < imRs.Rows; i++)
  781. {
  782. for (int j = 0; j < imRs.Cols; j++)
  783. {
  784. afImRs[i, j] = imRs.At<float>(i, j);
  785. }
  786. */
  787. imRs = null;
  788. }
  789. for (int i = 0; i < numdir; i++)
  790. {
  791. //coordinates of points in this direction after rotation of filter
  792. MyFilter chere = c[i];
  793. //filter image for max value
  794. //zzzzz
  795. OUTmaxfilt3 fltrst;
  796. if (1 == iInterpolationMethod)
  797. {
  798. //201118 for Acceleration fltrst = maxfilt3ByCubicSpline(im, chere, numremele/*, dim*/, imRs, iProportion);
  799. fltrst = maxfilt3ByCubicSpline(im, chere, numremele/*, dim*/, afImRs, iProportion);
  800. }
  801. else if (2 == iInterpolationMethod)
  802. {
  803. fltrst = maxfilt3ByBilinear(im, chere, numremele/*, dim*/);
  804. }
  805. else
  806. {
  807. fltrst = maxfilt3ByNearest(im, chere, numremele/*, dim*/);
  808. }
  809. //structural filtering
  810. //filtim = max(filtim,(sumim - sum(maxim,4))/ (numpoints-numremele));
  811. int[] point = new int[2];
  812. for (point[0] = 0; point[0] < filtim.Rows; point[0]++)
  813. {
  814. for (point[1] = 0; point[1] < filtim.Cols; point[1]++)
  815. {
  816. float fTemp = filtim.At<float>(point[0], point[1]);
  817. /*201118 for Acceleration
  818. fTemp = Math.Max(fTemp,
  819. (fltrst.sumim[point[0], point[1]] - (fltrst.maxim[point[0], point[1]]).Sum()) / (fltrst.numpoints - numremele)
  820. );
  821. */
  822. //(fltrst.minim[point[0], point[1]]).Sum()
  823. fTemp = fTemp = Math.Max(fTemp, (fltrst.minim[point[0]][point[1]].Take<float>(fltrst.numpoints - numremele)).Sum() / (fltrst.numpoints - numremele));
  824. filtim.Set<float>(point, fTemp);
  825. }
  826. }
  827. }
  828. return filtim;
  829. }
  830. OUTmaxfilt3 maxfilt3ByNearest(Mat im, MyFilter chere, int numremele/*, int[] dim*/)
  831. {
  832. /////Mat imRs = new Mat();
  833. /////im.ConvertTo(imRs, MatType.CV_32F);
  834. int BigRows = im.Rows;
  835. int BigCols = im.Cols;
  836. OUTmaxfilt3 rst = new OUTmaxfilt3();
  837. rst.sumim = new float[im.Rows, im.Cols];
  838. rst.maxim = new List<float>[im.Rows, im.Cols];
  839. for (int i = 0; i < im.Rows; i++)
  840. {
  841. for (int j = 0; j < im.Cols; j++)
  842. {
  843. (rst.sumim)[i, j] = 0;
  844. List<float> lisTmp = new List<float>();
  845. for (int k = 0; k < numremele; k++)
  846. {
  847. lisTmp.Add(0);
  848. }
  849. (rst.maxim)[i, j] = lisTmp;
  850. }
  851. }
  852. rst.numpoints = chere.x.Length;
  853. for (int i = 0; i < rst.numpoints; i++)
  854. {
  855. double xhere;
  856. double yhere;
  857. int[] point = new int[2];
  858. for (point[0] = 0; point[0] < im.Rows; point[0]++)
  859. {
  860. for (point[1] = 0; point[1] < im.Cols; point[1]++)
  861. {
  862. xhere = (point[0] + (chere.x)[i]);
  863. yhere = (point[1] + (chere.y)[i]);
  864. int iX = Math.Min(Math.Max((int)(xhere + 0.5), 0), BigRows - 1);
  865. int iY = Math.Min(Math.Max((int)(yhere + 0.5), 0), BigCols - 1);
  866. float fTemp = im.At<byte>(iX, iY);
  867. (rst.sumim)[point[0], point[1]] += fTemp;
  868. (rst.maxim)[point[0], point[1]].Add(fTemp);
  869. (rst.maxim)[point[0], point[1]].Sort();
  870. (rst.maxim)[point[0], point[1]].RemoveAt(0);
  871. (rst.maxim)[point[0], point[1]].Reverse();
  872. }
  873. }
  874. }
  875. return rst;
  876. }
  877. OUTmaxfilt3 maxfilt3ByBilinear(Mat im, MyFilter chere, int numremele/*, int[] dim*/)
  878. {
  879. /////Mat imRs = new Mat();
  880. /////im.ConvertTo(imRs, MatType.CV_32F);
  881. int BigRows = im.Rows;
  882. int BigCols = im.Cols;
  883. OUTmaxfilt3 rst = new OUTmaxfilt3();
  884. rst.sumim = new float[im.Rows, im.Cols];
  885. rst.maxim = new List<float>[im.Rows, im.Cols];
  886. for (int i = 0; i < im.Rows; i++)
  887. {
  888. for (int j = 0; j < im.Cols; j++)
  889. {
  890. (rst.sumim)[i, j] = 0;
  891. List<float> lisTmp = new List<float>();
  892. for (int k = 0; k < numremele; k++)
  893. {
  894. lisTmp.Add(0);
  895. }
  896. (rst.maxim)[i, j] = lisTmp;
  897. }
  898. }
  899. rst.numpoints = chere.x.Length;
  900. for (int i = 0; i < rst.numpoints; i++)
  901. {
  902. double xhere;
  903. double yhere;
  904. int[] point = new int[2];
  905. for (point[0] = 0; point[0] < im.Rows; point[0]++)
  906. {
  907. for (point[1] = 0; point[1] < im.Cols; point[1]++)
  908. {
  909. xhere = point[0] + (chere.x)[i];
  910. yhere = point[1] + (chere.y)[i];
  911. int iXS = Math.Min(Math.Max((int)(xhere), 0), BigRows - 1);
  912. int iYS = Math.Min(Math.Max((int)(yhere), 0), BigCols - 1);
  913. int iXB = Math.Min(Math.Max((int)(xhere + 1.0), 0), BigRows - 1);
  914. int iYB = Math.Min(Math.Max((int)(yhere + 1.0), 0), BigCols - 1);
  915. double dWXB = Math.Min(Math.Max((xhere - (double)iXS), 0.0), 1.0);
  916. double dWXS = 1.0 - dWXB;
  917. double dWYB = Math.Min(Math.Max((yhere - (double)iYS), 0.0), 1.0);
  918. double dWYS = 1.0 - dWYB;
  919. double dTempA = im.At<byte>(iXS, iYS);
  920. double dTempB = im.At<byte>(iXS, iYB);
  921. double dTempC = im.At<byte>(iXB, iYS);
  922. double dTempD = im.At<byte>(iXB, iYB);
  923. double dTempAB = dTempA * dWYS + dTempB * dWYB;
  924. double dTempCD = dTempC * dWYS + dTempD * dWYB;
  925. float fTemp = (float)(dTempAB * dWXS + dTempCD * dWXB);
  926. (rst.sumim)[point[0], point[1]] += fTemp;
  927. (rst.maxim)[point[0], point[1]].Add(fTemp);
  928. (rst.maxim)[point[0], point[1]].Sort();
  929. (rst.maxim)[point[0], point[1]].RemoveAt(0);
  930. (rst.maxim)[point[0], point[1]].Reverse();
  931. }
  932. }
  933. }
  934. return rst;
  935. }
  936. //201118 for Acceleration OUTmaxfilt3 maxfilt3ByCubicSpline(Mat im, MyFilter chere, int numremele/*, int[] dim*/, Mat imRs, int iProportion)
  937. OUTmaxfilt3 maxfilt3ByCubicSpline(Mat im, MyFilter chere, int numremele, float[] afImRs, int iProportion)
  938. {
  939. /////Mat imFt = new Mat();
  940. /////Mat imRs = new Mat();
  941. /////im.ConvertTo(imFt, MatType.CV_32F);
  942. /////int iProportion = 5;
  943. /////Cv2.Resize(imFt, imRs, new Size(imFt.Cols * iProportion, imFt.Rows * iProportion), 0, 0, InterpolationFlags.Cubic);
  944. //201118 for Acceleration int BigRows = imRs.Rows;
  945. //201118 for Acceleration int BigCols = imRs.Cols;
  946. int BigRows = im.Rows * iProportion;
  947. int BigCols = im.Cols * iProportion;
  948. /*
  949. double[,] x = new double[dim[0], dim[1]];
  950. double[,] y = new double[dim[0], dim[1]];
  951. for (int i = 0; i < dim[0]; i++)
  952. {
  953. for (int j = 0; j < dim[1]; j++)
  954. {
  955. x[i, j] = (double)i;
  956. y[i, j] = (double)j;
  957. }
  958. }
  959. */
  960. OUTmaxfilt3 rst = new OUTmaxfilt3();
  961. //rst.maxim = new Mat[numremele];
  962. //201118 for Acceleration rst.sumim = new float[im.Rows, im.Cols];
  963. //201118 for Acceleration rst.maxim = new List<float>[im.Rows, im.Cols];
  964. rst.numpoints = chere.x.Length;
  965. rst.minim = new float[im.Rows][][];
  966. for (int i = 0; i < im.Rows; i++)
  967. {
  968. rst.minim[i] = new float[im.Cols][];
  969. for (int j = 0; j < im.Cols; j++)
  970. {
  971. rst.minim[i][j] = new float[rst.numpoints];
  972. //201118 for Acceleration (rst.sumim)[i, j] = 0;
  973. //201118 for Acceleration List<float> lisTmp = new List<float>();
  974. //201118 for Acceleration for (int k = 0; k < numremele; k++)
  975. //201118 for Acceleration {
  976. //201118 for Acceleration lisTmp.Add(0);
  977. //201118 for Acceleration }
  978. //201118 for Acceleration (rst.maxim)[i, j] = lisTmp;
  979. //201118 for Acceleration List<float> lisTmpMin = new List<float>();
  980. //201118 for Acceleration (rst.minim)[i, j] = lisTmpMin;
  981. }
  982. }
  983. //Mat imhere = new Mat(imFt.Rows, imFt.Cols, MatType.CV_32F, 0.0);
  984. /* 201118 for Acceleration
  985. for (int i = 0; i < rst.numpoints; i++)
  986. {
  987. //the coordinate where we want to find the values
  988. //NB!!!!!!!!!
  989. //Must not do this for z direction, then it goes wrong.
  990. //Do NOOOOOT replacestr any Inf or NaN by image values, then the filter
  991. //does not work anymore!!!!!!
  992. //xhere(xhere < h(1)) = h(1);xhere(xhere > dim(1)*h(1)) = dim(1)*h(1);
  993. //yhere(yhere < h(1)) = h(1);yhere(yhere > dim(2)*h(1)) = dim(2)*h(2);
  994. //double[,] xhere = new double[dim[0], dim[1]];
  995. //double[,] yhere = new double[dim[0], dim[1]];
  996. double xhere;
  997. double yhere;
  998. int[] point = new int[2];
  999. for (point[0] = 0; point[0] < im.Rows; point[0]++)
  1000. {
  1001. for (point[1] = 0; point[1] < im.Cols; point[1]++)
  1002. {
  1003. //xhere[i, j] = Math.Min(Math.Max(x[i, j]+(chere.x)[t],1),dim[0]);
  1004. //yhere[i, j] = Math.Min(Math.Max(y[i, j]+(chere.y)[t],1),dim[1]);
  1005. xhere = (point[0] + (chere.x)[i]) * iProportion;
  1006. yhere = (point[1] + (chere.y)[i]) * iProportion;
  1007. int iX = Math.Min(Math.Max((int)(xhere + 0.5), 0), BigRows - 1);
  1008. int iY = Math.Min(Math.Max((int)(yhere + 0.5), 0), BigCols - 1);
  1009. float fTemp = imRs.At<float>(iX, iY);
  1010. //imhere.Set<float>(point, fTemp);
  1011. (rst.sumim)[point[0], point[1]] += fTemp;
  1012. (rst.maxim)[point[0], point[1]].Add(fTemp);
  1013. (rst.maxim)[point[0], point[1]].Sort();
  1014. (rst.maxim)[point[0], point[1]].RemoveAt(0);
  1015. (rst.maxim)[point[0], point[1]].Reverse();
  1016. }
  1017. }
  1018. }
  1019. */
  1020. for (int ir = 0; ir < im.Rows; ir++)
  1021. {
  1022. for (int ic = 0; ic < im.Cols; ic++)
  1023. {
  1024. double xhere;
  1025. double yhere;
  1026. for (int ip = 0; ip < rst.numpoints; ip++)
  1027. {
  1028. xhere = (ir + (chere.x)[ip]) * iProportion;
  1029. yhere = (ic + (chere.y)[ip]) * iProportion;
  1030. int iX = Math.Min(Math.Max((int)(xhere + 0.5), 0), BigRows - 1);
  1031. int iY = Math.Min(Math.Max((int)(yhere + 0.5), 0), BigCols - 1);
  1032. //201118 for Acceleration float fTemp = imRs.At<float>(iX, iY);
  1033. float fTemp = afImRs[iX * BigCols + iY];
  1034. //201118 for Acceleration (rst.sumim)[ir, ic] += fTemp;
  1035. //201118 for Acceleration (rst.maxim)[ir, ic].Add(fTemp);
  1036. (rst.minim)[ir][ic][ip] = fTemp;
  1037. }
  1038. //201118 for Acceleration (rst.maxim)[ir, ic].Sort((x, y) => -x.CompareTo(y));
  1039. //201118 for Acceleration (rst.maxim)[ir, ic].RemoveRange(numremele, rst.numpoints - numremele);
  1040. Array.Sort((rst.minim)[ir][ic]);
  1041. //201118 for Acceleration (rst.minim)[ir, ic].Sort();
  1042. //201118 for Acceleration (rst.minim)[ir, ic].RemoveRange(rst.numpoints - numremele,numremele);
  1043. }
  1044. }
  1045. return rst;
  1046. }
  1047. MyFilter[] makefilter(double[,] deg, int p)
  1048. {
  1049. int iNum = deg.GetLength(0);
  1050. MyFilter[] c = new MyFilter[iNum];
  1051. //r = linspace(-p,p,7);
  1052. int iArrLength = 7;
  1053. double[] r = new double[iArrLength];
  1054. double dStep = p * 2.0 / (iArrLength - 1.0);
  1055. for (int i = 0; i < 7; i++)
  1056. {
  1057. r[i] = -1.0 * p + i * dStep;
  1058. }
  1059. /*
  1060. for i = 1 : size(deg,1)
  1061. % the degrees
  1062. theta = deg(i,1);
  1063. phi = deg(i,2);
  1064. % the positions
  1065. c(i).x = r*sind(phi)*cosd(theta);
  1066. c(i).y = r*sind(phi)*sind(theta);
  1067. c(i).z = r*cosd(phi);
  1068. end;
  1069. */
  1070. for (int i = 0; i < iNum; i++)
  1071. {
  1072. double theta = deg[i, 0];
  1073. double phi = deg[i, 1];
  1074. c[i] = new MyFilter();
  1075. c[i].x = new double[iArrLength];
  1076. c[i].y = new double[iArrLength];
  1077. c[i].z = new double[iArrLength];
  1078. for (int j = 0; j < iArrLength; j++)
  1079. {
  1080. (c[i].x)[j] = r[j] * Math.Sin(phi) * Math.Cos(theta); ;
  1081. (c[i].y)[j] = r[j] * Math.Sin(phi) * Math.Sin(theta); ;
  1082. (c[i].z)[j] = r[j] * Math.Cos(phi);
  1083. }
  1084. }
  1085. return c;
  1086. }
  1087. public Mat ProFroStandardImage(Mat GryImg, int iConnect, Color phaseColor)
  1088. {
  1089. //Mat GryImg = new Mat();
  1090. ////转为为灰度?
  1091. //if (3 == OrgImg.Channels())
  1092. //{
  1093. // Cv2.CvtColor(OrgImg, GryImg, ColorConversionCodes.RGB2GRAY);
  1094. //}
  1095. //else
  1096. //{
  1097. // if (1 == OrgImg.Channels())
  1098. // {
  1099. // GryImg = OrgImg.Clone();
  1100. // }
  1101. // else
  1102. // {
  1103. // return null;
  1104. // }
  1105. //}
  1106. Mat CrystalImg = new Mat();
  1107. Mat BoundaryImg = new Mat();
  1108. Mat mat_mean = new Mat(), mat_stddev = new Mat();
  1109. double m, s, d = 0.5;
  1110. Cv2.MeanStdDev(GryImg, mat_mean, mat_stddev);
  1111. m = mat_mean.At<double>(0, 0);
  1112. s = mat_stddev.At<double>(0, 0);
  1113. //Cv2.Threshold(GryImg, CrystalImg, (int)Math.Min(m+d*s,230), 255, ThresholdTypes.Binary);
  1114. //Cv2.Threshold(GryImg, CrystalImg, 0, 1, ThresholdTypes.Otsu);
  1115. Cv2.Threshold(GryImg, CrystalImg, m, 255, ThresholdTypes.Binary);
  1116. //Cv2.ImShow("src", CrystalImg);//kkkkk
  1117. //Cv2.WaitKey(0);//kkkkk
  1118. int diam = 3;//mmmmm
  1119. Mat kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(diam, diam), new OpenCvSharp.Point(-1, -1));
  1120. //Cv2.Erode(CrystalImg, CrystalImg, kernel);
  1121. Cv2.MorphologyEx(CrystalImg, CrystalImg, MorphTypes.Open, kernel);
  1122. Cv2.BitwiseNot(CrystalImg, BoundaryImg);
  1123. //kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(diam, diam), new Point(-1, -1));
  1124. //Cv2.MorphologyEx(BoundaryImg, BoundaryImg, MorphTypes.Open, kernel);
  1125. //Cv2.MorphologyEx(BoundaryImg, BoundaryImg, MorphTypes.Close, kernel);
  1126. //Cv2.Dilate(BoundaryImg, BoundaryImg, kernel);
  1127. Class1 TCAlgo = new Class1();
  1128. TCAlgo.ImgThin(BoundaryImg);
  1129. //string filename = "D:\\temp.jpg";
  1130. //Cv2.ImWrite(filename, BoundaryImg);
  1131. if (1 == iConnect)
  1132. {
  1133. TCAlgo.ConnectionBoundary(BoundaryImg, 108);
  1134. }
  1135. //Cv2.ImShow("wai", BoundaryImg);//kkkkk
  1136. //Cv2.WaitKey(0);//kkkkk
  1137. //Cv2.BitwiseNot(BoundaryImg, CrystalImg);
  1138. //diam = 9;
  1139. //kernel = Cv2.GetStructuringElement(MorphShapes.Cross, new Size(diam, diam), new Point(-1, -1));
  1140. //Cv2.MorphologyEx(BoundaryImg, BoundaryImg, MorphTypes.Close, kernel);
  1141. //Cv2.Erode(CrystalImg, CrystalImg, kernel);
  1142. //Cv2.MorphologyEx(CrystalImg, CrystalImg, MorphTypes.Open, kernel);
  1143. //Cv2.MorphologyEx(CrystalImg, CrystalImg, MorphTypes.Close, kernel);
  1144. //Cv2.ImShow("nei", CrystalImg);//kkkkk
  1145. //Cv2.WaitKey(0);//kkkkk
  1146. /*
  1147. Mat watermark = new Mat(CrystalImg.Size(), MatType.CV_32S);
  1148. Point[][] contour;
  1149. HierarchyIndex[] hier;
  1150. Cv2.FindContours(CrystalImg, out contour, out hier, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple, null);
  1151. for (int i = 0; i < hier.Length; i++)
  1152. {
  1153. Cv2.DrawContours(watermark, contour, i, Scalar.All(i + 1), 1, LineTypes.Link8, hier);
  1154. }
  1155. Cv2.Watershed(OrgImg, watermark);
  1156. BoundaryImg = new Mat(watermark.Size(), MatType.CV_8UC3);
  1157. //ttttt Cv2.DrawContours(rtn.wat, contour, -1, Scalar.Red);
  1158. */
  1159. /*
  1160. Mat NewWat = new Mat();
  1161. Cv2.BitwiseNot(CrystalImg, NewWat);
  1162. Cv2.ImShow("bian", NewWat);//kkkkk
  1163. Cv2.WaitKey(0);//kkkkk
  1164. ImgThin(NewWat);
  1165. int Rows = NewWat.Rows;
  1166. int Cols = NewWat.Cols;
  1167. */
  1168. int[] point = new int[2];
  1169. Vec4b redcol;
  1170. if (phaseColor != null)
  1171. {
  1172. redcol = new Vec4b(phaseColor.B, phaseColor.G, phaseColor.R, 255);
  1173. }
  1174. else
  1175. redcol = new Vec4b(0, 0, 255/*255*/, 255);
  1176. Mat WAT = new Mat(BoundaryImg.Size(), MatType.CV_8UC4);
  1177. for (point[0] = 0; point[0] < WAT.Rows; point[0]++)
  1178. {
  1179. for (point[1] = 0; point[1] < WAT.Cols; point[1]++)
  1180. {
  1181. if (0 < BoundaryImg.At<byte>(point[0], point[1]))
  1182. {
  1183. WAT.Set<Vec4b>(point, redcol);
  1184. }
  1185. }
  1186. }
  1187. return WAT;
  1188. }
  1189. }
  1190. }