NewSeg.cs 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using OpenCvSharp;
  7. using System.Runtime.InteropServices;
  8. namespace NewSegDll
  9. {
  10. class InParameter
  11. {
  12. public int iMethod;
  13. public Mat MGryImg;
  14. public Mat MHesOutImage;
  15. public Mat MValley;
  16. public int iDimA;
  17. public int iDimB;
  18. public int iXiHua;
  19. public int iLianJie;
  20. //for Method2
  21. public Mat MEdgeOutImage;
  22. //for Method3
  23. public Form1 m_fmForMethod3;
  24. public int[] m_aiTrackBarMethod3;
  25. public Mat m_Mbinaryzation;
  26. public int m_iWhichBlur = 0;
  27. public int m_iMethod3DoSeg = 0;
  28. }
  29. public class NewSeg
  30. {
  31. Mat m_MOrgImg;
  32. public Mat m_MOutImg;
  33. double[] m_adOutParam;
  34. InParameter m_InParam;
  35. public int DoSeg(Mat _MOrgImg, Mat _MOutImg, double[] _adOutParam)
  36. {
  37. m_MOrgImg = _MOrgImg;
  38. m_MOutImg = _MOutImg;
  39. m_adOutParam = _adOutParam;
  40. PrepareParameter();
  41. if(2 == m_InParam.iMethod)
  42. {
  43. DetectEdge();
  44. return 2;
  45. }
  46. else if(3 == m_InParam.iMethod)
  47. {
  48. ShowMethod3Form();
  49. return 3;
  50. }
  51. ////Cv2.ImShow("[原图]", m_InParam.MGryImg);
  52. ////Cv2.WaitKey(0);
  53. //ImgHessian();
  54. //FindValley();
  55. //FindShed();
  56. return 1;
  57. }
  58. private int PrepareParameter()
  59. {
  60. m_InParam = new InParameter();
  61. m_InParam.MGryImg = new Mat();
  62. m_InParam.m_fmForMethod3 = new Form1();
  63. m_InParam.m_aiTrackBarMethod3 = new int[6];
  64. m_InParam.m_aiTrackBarMethod3[0] = 0;
  65. m_InParam.m_aiTrackBarMethod3[1] = 120;
  66. m_InParam.m_aiTrackBarMethod3[2] = 1;
  67. m_InParam.m_aiTrackBarMethod3[3] = 2;
  68. m_InParam.m_aiTrackBarMethod3[4] = 5;
  69. m_InParam.m_aiTrackBarMethod3[5] = 1;
  70. m_InParam.m_Mbinaryzation = new Mat();
  71. //转为为灰度?
  72. if (3 == m_MOrgImg.Channels())
  73. {
  74. Cv2.CvtColor(m_MOrgImg, m_InParam.MGryImg, ColorConversionCodes.RGB2GRAY);
  75. }
  76. else
  77. {
  78. if (1 == m_MOrgImg.Channels())
  79. {
  80. m_InParam.MGryImg = m_MOrgImg.Clone();
  81. }
  82. else
  83. {
  84. return -1;
  85. }
  86. }
  87. m_InParam.iMethod = 1;
  88. m_InParam.iDimA = 3;
  89. m_InParam.iDimB = 1;
  90. bool bFanSe = false;
  91. int iTiaoZheng = 0;
  92. double dTZXS = 1.0;
  93. double dK = 1.0;
  94. double dB = 0.0;
  95. m_InParam.iXiHua = 0;
  96. m_InParam.iLianJie = 0;
  97. if (m_adOutParam != null)
  98. {
  99. /*
  100. if((m_adOutParam[0] > 1.5)&&(m_adOutParam[0] < 2.5))
  101. {
  102. m_InParam.iMethod = 2;
  103. }
  104. if ((m_adOutParam[0] > 2.5) && (m_adOutParam[0] < 3.5))
  105. {
  106. m_InParam.iMethod = 3;
  107. }
  108. */
  109. m_InParam.iMethod = (int)(m_adOutParam[0] + 0.5);
  110. if ((m_adOutParam[1] > m_adOutParam[0]) && (m_adOutParam[1] < 2.5))
  111. {
  112. bFanSe = true;
  113. }
  114. if ((m_adOutParam[2] > 0.5) && (m_adOutParam[2] < 100.5))
  115. {
  116. m_InParam.iDimA = (int)(m_adOutParam[2] + 0.5);
  117. }
  118. if ((m_adOutParam[3] > 0.5) && (m_adOutParam[3] < 100.5))
  119. {
  120. m_InParam.iDimB = (int)(m_adOutParam[3] + 0.5);
  121. }
  122. if ((m_adOutParam[4] > 1.5) && (m_adOutParam[4] < 2.5))
  123. {
  124. iTiaoZheng = 2;
  125. dTZXS = Math.Max(m_adOutParam[5], 1.0);
  126. }
  127. else if ((m_adOutParam[4] > 2.5) && (m_adOutParam[4] < 3.5))
  128. {
  129. iTiaoZheng = 3;
  130. dTZXS = Math.Max(m_adOutParam[5], 1.0);
  131. }
  132. else if ((m_adOutParam[4] > 3.5) && (m_adOutParam[4] < 4.5))
  133. {
  134. iTiaoZheng = 4;
  135. dK = m_adOutParam[6];
  136. dB = m_adOutParam[7];
  137. }
  138. if ((m_adOutParam[8] > 1.5) && (m_adOutParam[8] < 2.5))
  139. {
  140. m_InParam.iXiHua = 2;
  141. }
  142. if ((m_adOutParam[9] > 1.5) && (m_adOutParam[9] < 2.5))
  143. {
  144. m_InParam.iLianJie = 2;
  145. }
  146. }
  147. if ((bFanSe) || (iTiaoZheng > 1))
  148. {
  149. int Rows = m_InParam.MGryImg.Rows;
  150. int Cols = m_InParam.MGryImg.Cols;
  151. int[] point = new int[2];
  152. //Vec3b redcol = new Vec3b(0, 0, 255);
  153. for (point[0] = 0; point[0] < Rows; point[0]++)
  154. {
  155. for (point[1] = 0; point[1] < Cols; point[1]++)
  156. {
  157. Byte bTemp = m_InParam.MGryImg.At<Byte>(point);
  158. if (bFanSe)
  159. {
  160. bTemp = (Byte)(255 - bTemp);
  161. }
  162. if (2 == iTiaoZheng)
  163. {
  164. bTemp = (Byte)((double)bTemp / dTZXS + 0.5);
  165. }
  166. if (3 == iTiaoZheng)
  167. {
  168. double dtt = 255.0 - bTemp;
  169. dtt = dtt / dTZXS;
  170. bTemp = (Byte)(255 - dtt + 0.5);
  171. }
  172. if (4 == iTiaoZheng)
  173. {
  174. double dtt = dK * bTemp + dB;
  175. dtt = Math.Min(Math.Max(dtt, 0.0), 255.0);
  176. bTemp = (Byte)(dtt + 0.5);
  177. }
  178. m_InParam.MGryImg.Set<Byte>(point, bTemp);
  179. }
  180. }
  181. }
  182. m_InParam.MHesOutImage = new Mat();
  183. m_InParam.MValley = new Mat();
  184. m_InParam.MEdgeOutImage = new Mat();
  185. return 1;
  186. }
  187. private int ShowMethod3Form()
  188. {
  189. m_InParam.m_fmForMethod3.m_aiTrackBarMethod3 = m_InParam.m_aiTrackBarMethod3;
  190. m_InParam.m_fmForMethod3.m_MOrgImg = m_MOrgImg;
  191. m_InParam.m_fmForMethod3.MGryImg = m_InParam.MGryImg;
  192. m_InParam.m_fmForMethod3.m_Mbinaryzation = m_InParam.m_Mbinaryzation;
  193. m_InParam.m_fmForMethod3.m_iWhichBlur = m_InParam.m_iWhichBlur;
  194. m_InParam.m_fmForMethod3.NSeg = this;
  195. m_InParam.m_fmForMethod3.ShowDialog();
  196. //m_InParam.m_iWhichBlur = m_InParam.m_fmForMethod3.m_iWhichBlur;
  197. //m_InParam.m_iMethod3DoSeg = m_InParam.m_fmForMethod3.m_iMethod3DoSeg;
  198. //if (1 == m_InParam.m_iMethod3DoSeg)
  199. //{
  200. // Method3DoSeg();
  201. //}
  202. return 1;
  203. }
  204. public int Method3DoSegButonClickAction()
  205. {
  206. m_InParam.m_iWhichBlur = m_InParam.m_fmForMethod3.m_iWhichBlur;
  207. m_InParam.m_iMethod3DoSeg = m_InParam.m_fmForMethod3.m_iMethod3DoSeg;
  208. m_InParam.m_fmForMethod3.m_Mbinaryzation.CopyTo(m_InParam.MValley);
  209. FindShed();
  210. return 1;
  211. }
  212. private int Method3DoSeg()
  213. {
  214. m_InParam.m_fmForMethod3.m_Mbinaryzation.CopyTo(m_InParam.MValley);
  215. FindShed();
  216. return 1;
  217. }
  218. private int DetectEdge()
  219. {
  220. /*
  221. int height = m_InParam.MGryImg.Rows;
  222. int width = m_InParam.MGryImg.Cols;
  223. int SUB_WIDTH = 50,SUB_HEIGHT = 50;
  224. int M = width / SUB_WIDTH, N = height / SUB_HEIGHT;
  225. Mat image_cut;
  226. m_InParam.MValley = new Mat(height, width, MatType.CV_8UC1,Scalar.All(0));
  227. for(int j = 0; j < N; j ++)
  228. {
  229. for (int i = 0; i < M; i++)
  230. {
  231. Rect rect = new Rect(i * SUB_WIDTH, j * SUB_HEIGHT, SUB_WIDTH, SUB_HEIGHT);
  232. image_cut = new Mat(m_InParam.MGryImg, rect);
  233. double min,max;
  234. Point minloc,maxloc;
  235. Cv2.MinMaxLoc(image_cut, out min, out max, out minloc, out maxloc);
  236. m_InParam.MValley.Set<Byte>(maxloc.Y + j * SUB_HEIGHT, maxloc.X + i * SUB_WIDTH,255);
  237. }
  238. }
  239. */
  240. Mat JDMGryImg = new Mat();
  241. Cv2.Resize(m_InParam.MGryImg, JDMGryImg, new Size(m_InParam.MGryImg.Cols * 0.2, m_InParam.MGryImg.Rows * 0.2), 0, 0, InterpolationFlags.Linear);
  242. Cv2.Sobel(JDMGryImg, m_InParam.MEdgeOutImage, -1, 1, 1, 3);
  243. Cv2.Threshold(m_InParam.MEdgeOutImage, m_InParam.MEdgeOutImage, 20, 255, ThresholdTypes.Binary);
  244. Mat JDMEdge = new Mat();
  245. Cv2.Canny(JDMGryImg, JDMEdge, 50, 50, 3);
  246. m_InParam.MEdgeOutImage = m_InParam.MEdgeOutImage | JDMEdge;
  247. //Cv2.Threshold(m_InParam.MGryImg, m_InParam.MEdgeOutImage, 170, 255, ThresholdTypes.BinaryInv);
  248. Mat kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(7,7), new Point(-1, -1));
  249. Cv2.MorphologyEx(m_InParam.MEdgeOutImage, m_InParam.MEdgeOutImage, MorphTypes.Close, kernel);
  250. Mat MTemp0 = new Mat();
  251. Cv2.Threshold(JDMGryImg, MTemp0, 150, 255, ThresholdTypes.BinaryInv);
  252. m_InParam.MEdgeOutImage = m_InParam.MEdgeOutImage & MTemp0;
  253. //kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(2, 2), new Point(-1, -1));
  254. //Cv2.MorphologyEx(m_InParam.MEdgeOutImage, m_InParam.MEdgeOutImage, MorphTypes.Erode, kernel);
  255. //ImgThin(m_InParam.MEdgeOutImage,-1);
  256. //Cv2.ImShow("211", m_InParam.MEdgeOutImage);
  257. //Cv2.WaitKey(0);
  258. //LTQY();
  259. //Mat MTemp1 = new Mat();
  260. //Cv2.Resize(m_InParam.MEdgeOutImage, MTemp1, new Size(m_InParam.MGryImg.Cols * 0.2, m_InParam.MGryImg.Rows * 0.2), 0, 0, InterpolationFlags.Linear);
  261. //Cv2.ConnectedComponentsWithAlgorithm
  262. //ImgThin(MTemp);
  263. ConnectionBoundary(m_InParam.MEdgeOutImage, 108);
  264. Mat MTemp2 = new Mat();
  265. Cv2.BitwiseNot(m_InParam.MEdgeOutImage, MTemp2);
  266. kernel = Cv2.GetStructuringElement(MorphShapes.Cross, new Size(7, 7), new Point(-1, -1));
  267. Cv2.MorphologyEx(MTemp2, MTemp2, MorphTypes.Erode, kernel);
  268. //Cv2.ImShow("216", MTemp2);
  269. //Cv2.WaitKey(0);
  270. Mat MTemp3 = new Mat();
  271. Cv2.Resize(m_MOrgImg, MTemp3, new Size(MTemp2.Cols, MTemp2.Rows), 0, 0, InterpolationFlags.Linear);
  272. Mat watermark = new Mat(MTemp2.Size(), MatType.CV_32S);
  273. Point[][] contour;
  274. HierarchyIndex[] hier;
  275. Cv2.FindContours(MTemp2, out contour, out hier, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple, null);
  276. for (int i = 0; i < hier.Length; i++)
  277. {
  278. Cv2.DrawContours(watermark, contour, i, Scalar.All(i + 1), 1, LineTypes.Link8, hier);
  279. }
  280. Cv2.Watershed(MTemp3, watermark);//mmmmm
  281. Mat MTemp4 = new Mat(MTemp3.Rows, MTemp3.Cols, MatType.CV_8UC1, Scalar.All(0));
  282. int Rows = watermark.Rows;
  283. int Cols = watermark.Cols;
  284. int[] point = new int[2];
  285. //Vec3b redcol = new Vec3b(0, 0, 255);
  286. for (point[0] = 0; point[0] < Rows; point[0]++)
  287. {
  288. for (point[1] = 0; point[1] < Cols; point[1]++)
  289. {
  290. if (0 >= watermark.At<int>(point[0], point[1]))
  291. {
  292. MTemp4.Set<Byte>(point, 255);
  293. }
  294. }
  295. }
  296. //Cv2.ImShow("219", MTemp4);
  297. //Cv2.WaitKey(0);
  298. Cv2.Resize(MTemp4, MTemp4, new Size(m_InParam.MGryImg.Cols, m_InParam.MGryImg.Rows), 0, 0, InterpolationFlags.Linear);
  299. //Cv2.Resize(MTemp, m_InParam.MEdgeOutImage, new Size(m_InParam.MGryImg.Cols, m_InParam.MGryImg.Rows), 0, 0, InterpolationFlags.Linear);
  300. //Cv2.ImShow("215", MTemp4);
  301. //Cv2.ImWrite("D:\\temp.bmp", m_InParam.MEdgeOutImage);
  302. //Cv2.ImShow("212", m_InParam.MValley);
  303. //Cv2.WaitKey(0);
  304. //Cv2.ImShow("219", MTemp4);
  305. //Cv2.WaitKey(0);
  306. Cv2.Resize(MTemp4, MTemp4, new Size(m_InParam.MGryImg.Cols, m_InParam.MGryImg.Rows), 0, 0, InterpolationFlags.Linear);
  307. //int[] point = new int[2];
  308. Vec3b redcol = new Vec3b(0, 0, 255);
  309. Rows = m_MOutImg.Rows;
  310. Cols = m_MOutImg.Cols;
  311. for (point[0] = 0; point[0] < Rows; point[0]++)
  312. {
  313. for (point[1] = 0; point[1] < Cols; point[1]++)
  314. {
  315. if (120 < MTemp4.At<Byte>(point[0], point[1]))
  316. {
  317. m_MOutImg.Set<Vec3b>(point, redcol);
  318. }
  319. }
  320. }
  321. /*
  322. Cv2.BitwiseNot(m_InParam.MEdgeOutImage, m_InParam.MValley);
  323. Size bianjieSize = m_InParam.MValley.Size();
  324. Mat Temp = Mat.Zeros(bianjieSize.Height + 2, bianjieSize.Width + 2, m_InParam.MValley.Type());//延展图像
  325. m_InParam.MValley.CopyTo(Temp.SubMat(new Range(1, bianjieSize.Height + 1), new Range(1, bianjieSize.Width + 1)));
  326. Cv2.FloodFill(Temp, new Point(0, 0), new Scalar(255));
  327. Mat cutImg = new Mat();
  328. Temp.SubMat(new Range(1, bianjieSize.Height + 1), new Range(1, bianjieSize.Width + 1)).CopyTo(cutImg);
  329. Cv2.BitwiseNot(cutImg, cutImg);
  330. m_InParam.MValley = m_InParam.MValley | cutImg;
  331. kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(2, 2), new Point(-1, -1));
  332. Cv2.MorphologyEx(m_InParam.MValley, m_InParam.MValley, MorphTypes.Close, kernel);
  333. Cv2.ImShow("213", m_InParam.MValley);
  334. Cv2.WaitKey(0);
  335. */
  336. return 1;
  337. }
  338. public int LTQY()
  339. {
  340. Mat img_bool, labels = new Mat(), stats = new Mat(), centroids = new Mat(), img_color;
  341. img_bool = m_InParam.MEdgeOutImage;
  342. int nccomps = Cv2.ConnectedComponentsWithStats (
  343. img_bool, //二值图像
  344. labels, //和原图一样大的标记图
  345. stats, //nccomps×5的矩阵 表示每个连通区域的外接矩形和面积(pixel)
  346. centroids //nccomps×2的矩阵 表示每个连通区域的质心
  347. );
  348. //显示原图统计结果
  349. char[] title = new char[1024];
  350. //sprintf(title,"原图中连通区域数:%d\n",nccomps);
  351. //cv::String num_connect(title);
  352. //cv::imshow(num_connect, img_bool);
  353. //去除过小区域,初始化颜色表
  354. //vector<cv::Vec3b> colors(nccomps);
  355. int[] colors = new int[nccomps];
  356. //colors[0] = cv::Vec3b(0,0,0); // background pixels remain black.
  357. for(int i = 1; i < nccomps; i++ ) {
  358. colors[i] = 255;
  359. //去除面积小于100的连通域
  360. if( stats.At<int>(i, 4) < 20 )
  361. colors[i] = 0; // small regions are painted with black too.
  362. }
  363. //按照label值,对不同的连通域进行着色
  364. img_color = new Mat(img_bool.Rows,img_bool.Cols, MatType.CV_8UC1,Scalar.All(0));
  365. for( int y = 0; y < img_color.Rows; y++ )
  366. for( int x = 0; x < img_bool.Cols; x++ )
  367. {
  368. int label = labels.At<int>(y, x);
  369. //CV_Assert(0 <= label && label <= nccomps);
  370. img_color.Set<Byte>(y, x,(Byte)colors[label]);
  371. }
  372. /*
  373. //统计降噪后的连通区域
  374. cv::cvtColor(img_color,img_gray,cv::COLOR_BGR2GRAY);
  375. cv::threshold(img_gray, img_gray, 1, 255, cv::THRESH_BINARY);
  376. nccomps = cv::connectedComponentsWithStats (img_gray, labels,stats,centroids);
  377. sprintf(title,"过滤小目标后的连通区域数量:%d\n",nccomps);
  378. num_connect = title;
  379. */
  380. //Cv2.ImShow("217", img_color);
  381. //Cv2.WaitKey(0);
  382. return 0;
  383. }
  384. public void ImgThin(Mat src, int maxIterations = -1)
  385. {
  386. //if (src.empty()) return;//图像为空,直接返回
  387. Cv2.Threshold(src, src, 100, 1, ThresholdTypes.Binary);//转为0或1的图像
  388. int ImgHeight = src.Rows;
  389. int ImgWidth = src.Cols;
  390. int count = 0; //记录迭代次数
  391. while (true)
  392. {
  393. count++;
  394. if (maxIterations != -1 && count > maxIterations) //限制次数并且迭代次数到达
  395. break;
  396. //vector<pair<int, int> > mFlag; //用于标记需要删除的点
  397. List<int[]> mFlag = new List<int[]>();
  398. //对点标记
  399. for (int i = 0; i < ImgHeight; ++i)
  400. {
  401. for (int j = 0; j < ImgWidth; ++j)
  402. {
  403. //如果满足四个条件,进行标记
  404. // p9 p2 p3
  405. // p8 p1 p4
  406. // p7 p6 p5
  407. int p1 = src.At<byte>(i, j);
  408. int p2 = (i == 0) ? 0 : src.At<byte>(i - 1, j);
  409. int p3 = (i == 0 || j == ImgWidth - 1) ? 0 : src.At<byte>(i - 1, j + 1);
  410. int p4 = (j == ImgWidth - 1) ? 0 : src.At<byte>(i, j + 1);
  411. int p5 = (i == ImgHeight - 1 || j == ImgWidth - 1) ? 0 : src.At<byte>(i + 1, j + 1);
  412. int p6 = (i == ImgHeight - 1) ? 0 : src.At<byte>(i + 1, j);
  413. int p7 = (i == ImgHeight - 1 || j == 0) ? 0 : src.At<byte>(i + 1, j - 1);
  414. int p8 = (j == 0) ? 0 : src.At<byte>(i, j - 1);
  415. int p9 = (i == 0 || j == 0) ? 0 : src.At<byte>(i - 1, j - 1);
  416. if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2 && (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6)
  417. {
  418. int ap = 0;
  419. if (p2 == 0 && p3 == 1) ++ap;
  420. if (p3 == 0 && p4 == 1) ++ap;
  421. if (p4 == 0 && p5 == 1) ++ap;
  422. if (p5 == 0 && p6 == 1) ++ap;
  423. if (p6 == 0 && p7 == 1) ++ap;
  424. if (p7 == 0 && p8 == 1) ++ap;
  425. if (p8 == 0 && p9 == 1) ++ap;
  426. if (p9 == 0 && p2 == 1) ++ap;
  427. if (ap == 1)
  428. {
  429. if (p2 * p4 * p6 == 0)
  430. {
  431. if (p4 * p6 * p8 == 0)
  432. {
  433. //标记
  434. //mFlag.push_back(make_pair(i, j));
  435. mFlag.Add(new int[2] { i, j });
  436. }
  437. }
  438. }
  439. }
  440. }
  441. }
  442. //将标记的点删除
  443. /*
  444. for (Point2d i = mFlag.ForEach; i != mFlag.end(); ++i)
  445. {
  446. src.At<byte>(i->first, i->second) = 0;
  447. }
  448. */
  449. mFlag.ForEach(delegate(int[] aiP)
  450. {
  451. src.Set<byte>(aiP, 0);
  452. });
  453. //直到没有点满足,算法结束
  454. //if (mFlag.size() == 0) break;
  455. //else mFlag.clear();//将mFlag清空
  456. if (mFlag.Count() == 0) break;
  457. else mFlag.Clear();
  458. //对点标记
  459. for (int i = 0; i < ImgHeight; ++i)
  460. {
  461. for (int j = 0; j < ImgWidth; ++j)
  462. {
  463. //如果满足四个条件,进行标记
  464. // p9 p2 p3
  465. // p8 p1 p4
  466. // p7 p6 p5
  467. int p1 = src.At<byte>(i, j);
  468. if (p1 != 1) continue;
  469. int p2 = (i == 0) ? 0 : src.At<byte>(i - 1, j);
  470. int p3 = (i == 0 || j == ImgWidth - 1) ? 0 : src.At<byte>(i - 1, j + 1);
  471. int p4 = (j == ImgWidth - 1) ? 0 : src.At<byte>(i, j + 1);
  472. int p5 = (i == ImgHeight - 1 || j == ImgWidth - 1) ? 0 : src.At<byte>(i + 1, j + 1);
  473. int p6 = (i == ImgHeight - 1) ? 0 : src.At<byte>(i + 1, j);
  474. int p7 = (i == ImgHeight - 1 || j == 0) ? 0 : src.At<byte>(i + 1, j - 1);
  475. int p8 = (j == 0) ? 0 : src.At<byte>(i, j - 1);
  476. int p9 = (i == 0 || j == 0) ? 0 : src.At<byte>(i - 1, j - 1);
  477. if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2 && (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6)
  478. {
  479. int ap = 0;
  480. if (p2 == 0 && p3 == 1) ++ap;
  481. if (p3 == 0 && p4 == 1) ++ap;
  482. if (p4 == 0 && p5 == 1) ++ap;
  483. if (p5 == 0 && p6 == 1) ++ap;
  484. if (p6 == 0 && p7 == 1) ++ap;
  485. if (p7 == 0 && p8 == 1) ++ap;
  486. if (p8 == 0 && p9 == 1) ++ap;
  487. if (p9 == 0 && p2 == 1) ++ap;
  488. if (ap == 1)
  489. {
  490. if (p2 * p4 * p8 == 0)
  491. {
  492. if (p2 * p6 * p8 == 0)
  493. {
  494. //标记
  495. //mFlag.push_back(make_pair(i, j));
  496. mFlag.Add(new int[2] { i, j });
  497. }
  498. }
  499. }
  500. }
  501. }
  502. }
  503. //删除
  504. /*
  505. for (vector<pair<int, int> >::iterator i = mFlag.begin(); i != mFlag.end(); ++i)
  506. {
  507. src.At<byte>(i->first, i->second) = 0;
  508. }
  509. */
  510. mFlag.ForEach(delegate(int[] aiP)
  511. {
  512. src.Set<byte>(aiP, 0);
  513. });
  514. //直到没有点满足,算法结束
  515. //if (mFlag.size() == 0) break;
  516. //else mFlag.clear();//将mFlag清空
  517. if (mFlag.Count() == 0) break;
  518. else mFlag.Clear();
  519. }
  520. Cv2.Threshold(src, src, 0, 255, ThresholdTypes.Binary);//二值化图像
  521. }
  522. public void ConnectionBoundary(Mat Img, int iDistance)
  523. {
  524. Cv2.Threshold(Img, Img, 100, 1, ThresholdTypes.Binary);//转为0或1的图像
  525. Mat ConnectImg = Connectivity(Img);
  526. List<int[]> mFlag = new List<int[]>();
  527. List<int[]> lstaiDirection = new List<int[]>();
  528. int[] point = new int[2];
  529. for (point[0] = 1; point[0] < (Img.Rows - 1); point[0]++)
  530. {
  531. for (point[1] = 1; point[1] < (Img.Cols - 1); point[1]++)
  532. {
  533. if ((1 <= (Img.At<byte>(point[0], point[1]))) && (0 == (ConnectImg.At<byte>(point[0], point[1]))))
  534. {
  535. Img.Set<byte>(point, 0);
  536. }
  537. if ((1 <= (Img.At<byte>(point[0], point[1]))) && (1 == (ConnectImg.At<byte>(point[0], point[1]))))
  538. {
  539. mFlag.Add(new int[2] { point[0], point[1] });
  540. int i = 0, j = 0;
  541. for (i = -1; i <= 1; i++)
  542. {
  543. bool bFind = false;
  544. for (j = -1; j <= 1; j++)
  545. {
  546. if ((0 == i) && (0 == j))
  547. {
  548. continue;
  549. }
  550. if ((Img.At<byte>(point[0] + i, point[1] + j)) >= 1)
  551. {
  552. bFind = true;
  553. break;
  554. }
  555. }
  556. if (bFind)
  557. {
  558. break;
  559. }
  560. }
  561. lstaiDirection.Add(new int[2] { 0 - i, 0 - j });
  562. }
  563. }
  564. }
  565. int iCount = mFlag.Count();
  566. List<int[]>[] Development = new List<int[]>[iCount];
  567. List<int> NotFind = new List<int>();
  568. List<int> Used = new List<int>();
  569. for (int ii = 0; ii < iCount; ii++)
  570. {
  571. NotFind.Add(ii);
  572. int[] pnt = mFlag[ii];
  573. Development[ii] = new List<int[]>();
  574. Development[ii].Add(new int[2] { pnt[0], pnt[1] });
  575. }
  576. Mat TempImg = new Mat(Img.Size(), MatType.CV_32SC1);
  577. for (point[0] = 0; point[0] < Img.Rows; point[0]++)
  578. {
  579. for (point[1] = 0; point[1] < Img.Cols; point[1]++)
  580. {
  581. int Temp = Img.At<byte>(point[0], point[1]);
  582. TempImg.Set<int>(point, Temp);
  583. }
  584. }
  585. int[,] Neighbor = new int[260, 2] {{-1,0},{0,1},{1,0},{0,1}/*4*/,{-1,1},{1,1},{1,-1},{-1,-1}/*8*/,
  586. {-2,0},{0,2},{2,0},{0,-2}/*12*/,{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}/*20*/,
  587. {-2,2},{2,2},{2,-2},{-2,-2},{-3,0},{0,3},{3,0},{0,-3}/*28*/,
  588. {-3,1},{-1,3},{1,3},{3,1},{3,-1},{1,-3},{-1,-3},{-3,-1}/*36*/,
  589. {2,3},{-3,2},{-2,-3},{-2,3},{-3,-2},{3,2},{3,-2},{2,-3},
  590. {4,0},{0,4},{-4,0},{0,-4},{1,4},{4,-1},{4,1},{-1,-4},{-4,1},{-4,-1},{-1,4},{1,-4},{3,3},{3,-3},{-3,3},
  591. {-3,-3},{-4,-2},{-2,-4},{-4,2},{4,2},{-2,4},{4,-2},{2,-4},{2,4},{4,-3},{-3,4},{4,3},{5,0},{0,5},{0,-5},
  592. {-5,0},{3,4},{-3,-4},{-4,-3},{3,-4},{-4,3},{5,-1},{-1,5},{-1,-5},{5,1},{1,-5},{-5,1},{-5,-1},{1,5},{-2,5},
  593. {2,-5},{2,5},{5,2},{-5,2},{-2,-5},{5,-2},{-5,-2},{-4,4},{4,-4},{4,4},{-4,-4},{3,-5},{-5,3},{-3,5},{5,-3},
  594. {5,3},{-5,-3},{-3,-5},{3,5}/*108*/,{0,6},{0,-6},{-6,0},{6,0},{-6,1},{1,6},{-6,-1},{1,-6},{-1,6},{-1,-6},{6,-1},
  595. {6,1},{2,6},{-2,-6},{6,2},{-6,2},{2,-6},{-6,-2},{-2,6},{6,-2},{-5,-4},{5,4},{4,5},{-4,5},{4,-5},{-5,4},
  596. {5,-4},{-4,-5},{-3,6},{-6,3},{-3,-6},{-6,-3},{3,-6},{6,3},{3,6},{6,-3},{0,7},{7,0},{0,-7},{-7,0},{5,-5},
  597. {1,7},{-1,7},{-5,-5},{-7,-1},{-7,1},{-1,-7},{1,-7},{7,1},{-5,5},{5,5},{7,-1}/*160*/,{6,4},{-6,4},{6,-4},{-6,-4},
  598. {-4,-6},{4,6},{4,-6},{-4,6},{7,-2},{7,2},{2,7},{-7,-2},{-2,-7},{-2,7},{2,-7},{-7,2}/*176*/,{7,-3},{-3,7},{-3,-7},
  599. {3,-7},{-7,3},{3,7},{7,3},{-7,-3},{6,-5},{5,6},{5,-6},{6,5},{-5,6},{-5,-6},{-6,5},{-6,-5},{8,0},{0,-8},
  600. {-8,0},{0,8},{-4,7},{4,-7},{-8,-1},{-1,8},{-7,4},{-1,-8},{7,4},{1,-8},{1,8},{8,1},{8,-1},{-4,-7},{-7,-4},
  601. {7,-4},{-8,1},{4,7}/*212*/,{-2,8},{2,-8},{-2,-8},{8,2},{-8,2},{-8,-2},{2,8},{8,-2},{-6,6},{6,6},{6,-6},{-6,-6},
  602. {3,-8},{-3,8},{8,3},{8,-3},{3,8},{-3,-8},{-8,3},{-8,-3},{7,-5},{-7,-5},{5,7},{7,5},{5,-7},{-7,5},{-5,-7},
  603. {-5,7}/*240*/,{8,-4},{-4,-8},{-8,-4},{8,4},{4,8},{-8,4},{4,-8},{-4,8},{0,-9},{0,9},{-9,0},{9,0},{9,-1},{-9,-1},
  604. {1,-9},{-1,9},{-1,-9},{-9,1},{1,9},{9,1}/*260*/ };
  605. while (0 != NotFind.Count())
  606. {
  607. int ii = NotFind[0];
  608. NotFind.RemoveAt(0);
  609. int LastIndex = Development[ii].Count() - 1;
  610. int[] pntOld = (Development[ii])[LastIndex];
  611. int[] pnt = new int[2] { pntOld[0], pntOld[1] };
  612. int[] dir = lstaiDirection[ii];
  613. bool bHave = false;
  614. for (int nn = 0; nn < iDistance; nn++)
  615. {
  616. if ((0 > (dir[0] * Neighbor[nn, 0])) || (0 > (dir[1] * Neighbor[nn, 1])))
  617. {
  618. continue;
  619. }
  620. pnt[0] = pntOld[0] + Neighbor[nn, 0];
  621. pnt[1] = pntOld[1] + Neighbor[nn, 1];
  622. if ((0 > pnt[0]) || (Img.Rows <= pnt[0]) || (0 > pnt[1]) || (Img.Cols <= pnt[1]))
  623. {
  624. continue;
  625. }
  626. int iThisPnt = TempImg.At<int>(pnt[0], pnt[1]);
  627. if ((1 < iThisPnt) && (ii != iThisPnt))
  628. {
  629. NotFind.Remove(iThisPnt);
  630. if (false == Used.Contains(iThisPnt))
  631. {
  632. int FirstOne = (Development[iThisPnt]).FindIndex(t => (t[0] == pnt[0]) && (t[1] == pnt[1]));
  633. //.First(t => (t[0] == pnt[0]) && (t[1] == pnt[1]));
  634. int LastOne = Development[iThisPnt].Count() - 1;
  635. if (1 <= (LastOne - FirstOne))
  636. {
  637. for (int jj = FirstOne + 1; jj <= LastOne; jj++)
  638. {
  639. TempImg.Set<int>((Development[iThisPnt])[jj], 0);
  640. }
  641. (Development[iThisPnt]).RemoveRange(FirstOne + 1, LastOne - FirstOne);
  642. }
  643. Used.Add(iThisPnt);
  644. Used.Add(ii);
  645. }
  646. ConnectTwoPnt(pntOld, pnt, Development[ii]);
  647. bHave = true;
  648. break;
  649. }
  650. if (1 == iThisPnt)
  651. {
  652. ConnectTwoPnt(pntOld, pnt, Development[ii]);
  653. bHave = true;
  654. break;
  655. }
  656. }
  657. if (bHave)
  658. {
  659. continue;
  660. }
  661. pnt[0] = pntOld[0] + dir[0];
  662. pnt[1] = pntOld[1] + dir[1];
  663. if ((0 > pnt[0]) || (Img.Rows <= pnt[0]) || (0 > pnt[1]) || (Img.Cols <= pnt[1]))
  664. {
  665. continue;
  666. }
  667. /*
  668. if(1 <= TempImg.At<int>(pnt[0], pnt[1]))
  669. {
  670. continue;
  671. }
  672. */
  673. Development[ii].Add(pnt);
  674. TempImg.Set<int>(pnt, ii);
  675. NotFind.Add(ii);
  676. /*
  677. int iThisPnt = TempImg.At<int>(pnt[0], pnt[1]);
  678. if (1 < iThisPnt)
  679. {
  680. NotFind.Remove(iThisPnt);
  681. if(false == Used.Contains(iThisPnt))
  682. {
  683. int FirstOne = (Development[iThisPnt]).FindIndex(t => (t[0] == pnt[0]) && (t[1] == pnt[1]));
  684. //.First(t => (t[0] == pnt[0]) && (t[1] == pnt[1]));
  685. int LastOne = Development[iThisPnt].Count() - 1;
  686. if(1 <= (LastOne - FirstOne))
  687. {
  688. for (int jj = FirstOne + 1; jj <= LastOne; jj++)
  689. {
  690. TempImg.Set<int>((Development[iThisPnt])[jj], 0);
  691. }
  692. (Development[iThisPnt]).RemoveRange(FirstOne + 1, LastOne - FirstOne);
  693. }
  694. Used.Add(iThisPnt);
  695. Used.Add(ii);
  696. }
  697. }
  698. else if (0 >= iThisPnt)
  699. {
  700. Development[ii].Add(pnt);
  701. TempImg.Set<int>(pnt, ii);
  702. NotFind.Add(ii);
  703. }
  704. */
  705. }
  706. for (int ii = 0; ii < iCount; ii++)
  707. {
  708. Development[ii].ForEach(delegate(int[] aiP)
  709. {
  710. Img.Set<byte>(aiP, 1);
  711. });
  712. }
  713. Cv2.Threshold(Img, Img, 0, 255, ThresholdTypes.Binary);//二值化图像
  714. }
  715. public void ConnectTwoPnt(int[] pntA, int[] pntB, List<int[]> DevelopmentA)
  716. {
  717. int iXThis = pntA[0];
  718. int iYThis = pntA[1];
  719. int iXD = pntB[0] - iXThis;
  720. int iYD = pntB[1] - iYThis;
  721. int iSignX = 0 == iXD ? 0 : iXD / ((int)(Math.Abs(iXD)));
  722. int iSignY = 0 == iYD ? 0 : iYD / ((int)(Math.Abs(iYD)));
  723. while ((0 != iXD) || (0 != iYD))
  724. {
  725. if ((Math.Abs(iXD)) > (Math.Abs(iYD)))
  726. {
  727. iXThis += iSignX;
  728. }
  729. else
  730. {
  731. iYThis += iSignY;
  732. }
  733. DevelopmentA.Add(new int[2] { iXThis, iYThis });
  734. iXD = pntB[0] - iXThis;
  735. iYD = pntB[1] - iYThis;
  736. }
  737. }
  738. public Mat Connectivity(Mat Img)
  739. {
  740. Mat TempImg = new Mat(Img.Size(), MatType.CV_8UC1);
  741. int[] point = new int[2];
  742. for (point[0] = 1; point[0] < (Img.Rows - 1); point[0]++)
  743. {
  744. for (point[1] = 0; point[1] < Img.Cols; point[1]++)
  745. {
  746. byte Temp = Img.At<byte>(point[0] - 1, point[1]);
  747. Temp += Img.At<byte>(point[0], point[1]);
  748. Temp += Img.At<byte>(point[0] + 1, point[1]);
  749. TempImg.Set<byte>(point, Temp);
  750. }
  751. }
  752. Mat ConnectImg = new Mat(Img.Size(), MatType.CV_8UC1);
  753. for (point[0] = 1; point[0] < (Img.Rows - 1); point[0]++)
  754. {
  755. for (point[1] = 1; point[1] < (Img.Cols - 1); point[1]++)
  756. {
  757. byte Temp = TempImg.At<byte>(point[0], point[1] - 1);
  758. Temp += TempImg.At<byte>(point[0], point[1]);
  759. Temp += TempImg.At<byte>(point[0], point[1] + 1);
  760. Temp -= Img.At<byte>(point[0], point[1]);
  761. ConnectImg.Set<byte>(point, Temp);
  762. }
  763. }
  764. TempImg = null;
  765. return ConnectImg;
  766. }
  767. public Mat m_watermark;
  768. private int FindShed()
  769. {
  770. Mat watermark = new Mat(m_InParam.MValley.Size(), MatType.CV_32S);
  771. Point[][] contour;
  772. HierarchyIndex[] hier;
  773. Cv2.FindContours(m_InParam.MValley, out contour, out hier, RetrievalModes.CComp, ContourApproximationModes.ApproxSimple, null);
  774. for (int i = 0; i < hier.Length; i++)
  775. {
  776. Cv2.DrawContours(watermark, contour, i, Scalar.All(i + 1), 1, LineTypes.Link8, hier);
  777. }
  778. //Mat Temp = new Mat(imsegm.Size(), MatType.CV_8UC3);
  779. //imsegm.CopyTo(Temp);
  780. Cv2.Watershed(m_MOrgImg, watermark);//mmmmm
  781. int Rows = watermark.Rows;
  782. int Cols = watermark.Cols;
  783. int[] point = new int[2];
  784. Vec3b redcol = new Vec3b(0, 0, 255);
  785. for (point[0] = 0; point[0] < Rows; point[0]++)
  786. {
  787. for (point[1] = 0; point[1] < Cols; point[1]++)
  788. {
  789. if (0 >= watermark.At<int>(point[0], point[1]))
  790. {
  791. m_MOutImg.Set<Vec3b>(point, redcol);
  792. }
  793. }
  794. }
  795. m_watermark = watermark.Clone();
  796. //Cv2.ImShow("555", m_MOutImg);
  797. //Cv2.WaitKey(0);
  798. return 1;
  799. }
  800. private int FindValley()
  801. {
  802. //Cv2.BitwiseNot(m_InParam.MHesOutImage, m_InParam.MValley);
  803. Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(m_InParam.iDimA, m_InParam.iDimA), new Point(-1, -1));
  804. Cv2.MorphologyEx(m_InParam.MHesOutImage, m_InParam.MHesOutImage, MorphTypes.Close, kernel);
  805. //Cv2.ImShow("333", m_InParam.MHesOutImage);
  806. //Cv2.WaitKey(0);
  807. Cv2.BitwiseNot(m_InParam.MHesOutImage, m_InParam.MValley);
  808. //kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(m_InParam.iDimB, m_InParam.iDimB), new Point(-1, -1));
  809. //Cv2.MorphologyEx(m_InParam.MValley, m_InParam.MValley, MorphTypes.Open, kernel);
  810. //Cv2.MorphologyEx(m_InParam.MValley, m_InParam.MValley, MorphTypes.Close, kernel);
  811. Size bianjieSize = m_InParam.MValley.Size();
  812. Mat Temp = Mat.Zeros(bianjieSize.Height + 2, bianjieSize.Width + 2, m_InParam.MValley.Type());//延展图像
  813. m_InParam.MValley.CopyTo(Temp.SubMat(new Range(1, bianjieSize.Height + 1), new Range(1, bianjieSize.Width + 1)));
  814. Cv2.FloodFill(Temp, new Point(0, 0), new Scalar(255));
  815. Mat cutImg = new Mat();
  816. Temp.SubMat(new Range(1, bianjieSize.Height + 1), new Range(1, bianjieSize.Width + 1)).CopyTo(cutImg);
  817. Cv2.BitwiseNot(cutImg, cutImg);
  818. m_InParam.MValley = m_InParam.MValley | cutImg;
  819. //Cv2.ImShow("444", m_InParam.MValley);
  820. //Cv2.WaitKey(0);
  821. return 1;
  822. }
  823. private int ImgHessian()
  824. {
  825. //Mat srcImage = m_InParam.MGryImg;
  826. Mat srcImage = new Mat();
  827. m_InParam.MGryImg.ConvertTo(srcImage, MatType.CV_32F);
  828. int height = srcImage.Rows;
  829. int width = srcImage.Cols;
  830. //zk Mat outImage = new Mat(height, width, MatType.CV_8UC1,Scalar.All(0));
  831. int W = 5;
  832. double sigma = 1.2;
  833. Mat xxGauKernel = new Mat(2 * W + 1, 2 * W + 1, MatType.CV_32FC1, Scalar.All(0));
  834. Mat xyGauKernel = new Mat(2 * W + 1, 2 * W + 1, MatType.CV_32FC1, Scalar.All(0));
  835. Mat yyGauKernel = new Mat(2 * W + 1, 2 * W + 1, MatType.CV_32FC1, Scalar.All(0));
  836. //构建高斯二阶偏导数模板
  837. for (int i = -W; i <= W; i++)
  838. {
  839. for (int j = -W; j <= W; j++)
  840. {
  841. double tt1 = (1 - (i * i) / (sigma * sigma));
  842. double tt2 = Math.Exp(-1 * (i * i + j * j) / (2 * sigma * sigma));
  843. double tt3 = (-1 / (2 * Math.PI * Math.Pow(sigma, 4)));
  844. double t1 = tt1 * tt2 * tt3;
  845. float t2 = (float)t1;
  846. //Dxx = 1/(2*pi*sigma^4)*(x.^2/sigma^2-1).*exp(-(x.^2+y.^2)/(2*sigma^2))
  847. //double tt4 = 1.0 / (2.0 * Math.PI * Math.Pow(sigma, 4.0));
  848. //double tt5 = ((double)i * i / (sigma * sigma) - 1);
  849. //double tt6 = Math.Exp(-((double)i * i + (double)j * j) / (2 * sigma * sigma));
  850. //float t3 = (float)(tt4*tt5*tt6);
  851. xxGauKernel.Set<float>(i + W, j + W, t2);
  852. yyGauKernel.Set<float>(i + W, j + W, (float)((1 - (j * j) / (sigma * sigma)) * Math.Exp(-1 * (i * i + j * j) / (2 * sigma * sigma)) * (-1 / (2 * Math.PI * Math.Pow(sigma, 4)))));
  853. xyGauKernel.Set<float>(i + W, j + W, (float)(((i * j)) * Math.Exp(-1 * (i * i + j * j) / (2 * sigma * sigma)) * (1 / (2 * Math.PI * Math.Pow(sigma, 6)))));
  854. }
  855. }
  856. /*
  857. for (int i = 0; i < (2 * W + 1); i++)
  858. {
  859. for (int j = 0; j < (2 * W + 1); j++)
  860. {
  861. cout << xxGauKernel.at<float>(i, j) << " ";
  862. }
  863. cout << endl;
  864. }
  865. */
  866. Mat xxDerivae = new Mat(height, width, MatType.CV_32FC1, Scalar.All(0));
  867. Mat yyDerivae = new Mat(height, width, MatType.CV_32FC1, Scalar.All(0));
  868. Mat xyDerivae = new Mat(height, width, MatType.CV_32FC1, Scalar.All(0));
  869. //图像与高斯二阶偏导数模板进行卷积
  870. Cv2.Filter2D(srcImage, xxDerivae, xxDerivae.Depth(), xxGauKernel);
  871. Cv2.Filter2D(srcImage, yyDerivae, yyDerivae.Depth(), yyGauKernel);
  872. Cv2.Filter2D(srcImage, xyDerivae, xyDerivae.Depth(), xyGauKernel);
  873. //Cv2.ImShow("111", xxDerivae);
  874. //Cv2.WaitKey(0);
  875. //Cv2.ImShow("111", yyDerivae);
  876. //Cv2.WaitKey(0);
  877. //Cv2.ImShow("111", xyDerivae);
  878. //Cv2.WaitKey(0);
  879. //zk
  880. //Mat tmpImage = new Mat(height, width, MatType.CV_8UC1, Scalar.All(0));
  881. Byte[,] abtmpImage = new Byte[height, width];
  882. float fMavV = 0.0f;
  883. float fMinV = 999999.0f;
  884. float[] afImXX = new float[height * width];
  885. float[] afImYY = new float[height * width];
  886. float[] afImXY = new float[height * width];
  887. Marshal.Copy(xxDerivae.Data, afImXX, 0, height * width);
  888. Marshal.Copy(yyDerivae.Data, afImYY, 0, height * width);
  889. Marshal.Copy(xyDerivae.Data, afImXY, 0, height * width);
  890. for (int h = 0; h < height; h++)
  891. {
  892. for (int w = 0; w < width; w++)
  893. {
  894. //map<int, float> best_step;
  895. /* int HLx = h - STEP; if (HLx < 0){ HLx = 0; }
  896. int HUx = h + STEP; if (HUx >= height){ HUx = height - 1; }
  897. int WLy = w - STEP; if (WLy < 0){ WLy = 0; }
  898. int WUy = w + STEP; if (WUy >= width){ WUy = width - 1; }
  899. float fxx = srcImage.at<uchar>(h, WUy) + srcImage.at<uchar>(h, WLy) - 2 * srcImage.at<uchar>(h, w);
  900. float fyy = srcImage.at<uchar>(HLx, w) + srcImage.at<uchar>(HUx, w) - 2 * srcImage.at<uchar>(h, w);
  901. float fxy = 0.25*(srcImage.at<uchar>(HUx, WUy) + srcImage.at<uchar>(HLx, WLy) - srcImage.at<uchar>(HUx, WLy) - srcImage.at<uchar>(HLx, WUy));
  902. */
  903. //float fxx = xxDerivae.At<float>(h, w);
  904. //float fyy = yyDerivae.At<float>(h, w);
  905. //float fxy = xyDerivae.At<float>(h, w);
  906. float fxx = afImXX[h * width + w];
  907. float fyy = afImYY[h * width + w];
  908. float fxy = afImXY[h * width + w];
  909. /*
  910. //float myArray[2][2] = { { fxx, fxy }, { fxy, fyy } }; //构建矩阵,求取特征值
  911. float[,] myArray = new float[2, 2] { { fxx, fxy }, { fxy, fyy } };
  912. Mat Array = new Mat(2, 2, MatType.CV_32FC1, myArray);
  913. Mat eValue = new Mat();
  914. Mat eVector = new Mat();
  915. Cv2.Eigen(Array, eValue, eVector); //矩阵是降序排列的
  916. float a1 = eValue.At<float>(0, 0);
  917. float a2 = eValue.At<float>(1, 0);
  918. */
  919. double dT1 = (fxx + fyy) * (fxx + fyy) - 4 * (fxx * fyy - fxy * fxy);
  920. if (dT1 < 0)
  921. {
  922. continue;
  923. }
  924. dT1 = Math.Sqrt(dT1);
  925. double a1 = (fxx + fyy + dT1)/2.0;
  926. double a2 = (fxx + fyy - dT1) / 2.0;
  927. if ((a1 > 0) && (Math.Abs(a1) > (1 + Math.Abs(a2)))) //根据特征向量判断线性结构
  928. {
  929. /*
  930. //zk
  931. double t1 = Math.Pow((Math.Abs(a1) - Math.Abs(a2)), 4);
  932. //double t1 = Math.Pow((Math.Abs(a1) / Math.Abs(a2)) * (Math.Abs(a1) - Math.Abs(a2)), 1.5);
  933. float t2 = (float)t1;
  934. if(t2 > fMavV)
  935. {
  936. fMavV = t2;
  937. }
  938. if (t2 < fMinV)
  939. {
  940. fMinV = t2;
  941. }
  942. */
  943. //tmpImage.Set<Byte>(h, w, 2);
  944. //outImage.at<uchar>(h, w) = pow((ABS(a1) / ABS(a2))*(ABS(a1) - ABS(a2)), 1.5);
  945. abtmpImage[h, w] = (Byte)255;
  946. }
  947. }
  948. }
  949. //float fSegYuZhi = 1;
  950. //(fMavV - fMinV) * 0.00001f + fMinV;
  951. //m_InParam.MHesOutImage = new Mat(tmpImage.Size(), MatType.CV_8UC3);
  952. //Cv2.Threshold(tmpImage, m_InParam.MHesOutImage, 1, 255, ThresholdTypes.Binary);
  953. m_InParam.MHesOutImage = new Mat(height, width, MatType.CV_8UC1, abtmpImage); ;
  954. /*
  955. //----------做一个闭操作
  956. Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 2), new Point(-1, -1));
  957. Cv2.MorphologyEx(outImage, outImage, MorphTypes.Close, element);
  958. Cv2.ImWrite("D:\\temp.bmp", outImage);
  959. */
  960. //Cv2.ImShow("222", m_InParam.MHesOutImage);
  961. //Cv2.WaitKey(0);
  962. //Cv2.ImWrite("D:\\temp.bmp", m_InParam.MHesOutImage);
  963. return 0;
  964. }
  965. }
  966. }