You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1274 lines
50 KiB

  1. //----------------------------------------------------------------------------
  2. // Copyright (C) 2004-2021 by EMGU Corporation. All rights reserved.
  3. //----------------------------------------------------------------------------
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7. using System.Drawing;
  8. //using System.IO;
  9. using System.Text;
  10. using Emgu.CV;
  11. using Emgu.CV.Cuda;
  12. using Emgu.CV.CvEnum;
  13. using Emgu.CV.Structure;
  14. using Emgu.CV.Util;
  15. using Emgu.CV.Features2D;
  16. using Emgu.CV.XFeatures2D;
  17. using System.Runtime.InteropServices;
  18. #if !NETCOREAPP
  19. using Emgu.CV.UI;
  20. #endif
  21. #if VS_TEST
  22. using Microsoft.VisualStudio.TestTools.UnitTesting;
  23. using TestAttribute = Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute;
  24. using TestFixture = Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute;
  25. #elif NETFX_CORE
  26. using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
  27. using TestAttribute = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
  28. using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
  29. #else
  30. using NUnit.Framework;
  31. #endif
  32. namespace Emgu.CV.Test
  33. {
  34. [TestFixture]
  35. public class TestGpuMat
  36. {
  37. [Test]
  38. public void TestGetCudaEnabledDeviceCount()
  39. {
  40. if (CudaInvoke.HasCuda)
  41. {
  42. Trace.WriteLine(CudaInvoke.GetCudaDevicesSummary());
  43. }
  44. }
  45. /*
  46. public int MemTest()
  47. {
  48. while (true)
  49. {
  50. using (GpuMat<Byte> m = new GpuMat<Byte>(320, 240, 1))
  51. {
  52. }
  53. }
  54. }*/
  55. [Test]
  56. public void TestCudaImageAsyncOps()
  57. {
  58. if (CudaInvoke.HasCuda)
  59. {
  60. int counter = 0;
  61. Stopwatch watch = Stopwatch.StartNew();
  62. using (GpuMat img1 = new GpuMat(3000, 2000, DepthType.Cv8U, 3))
  63. using (GpuMat img2 = new GpuMat(3000, 2000, DepthType.Cv8U, 3))
  64. using (GpuMat img3 = new GpuMat())
  65. using (Stream stream = new Stream())
  66. using (GpuMat mat1 = new GpuMat())
  67. {
  68. img1.ConvertTo(mat1, DepthType.Cv8U, 1, 0, stream);
  69. while (!stream.Completed)
  70. {
  71. if (counter <= int.MaxValue) counter++;
  72. }
  73. Trace.WriteLine(String.Format("Counter has been incremented {0} times", counter));
  74. counter = 0;
  75. CudaInvoke.CvtColor(img2, img3, CvToolbox.GetColorCvtCode(typeof(Bgr), typeof(Gray)), 1, stream);
  76. while (!stream.Completed)
  77. {
  78. if (counter <= int.MaxValue) counter++;
  79. }
  80. Trace.WriteLine(String.Format("Counter has been incremented {0} times", counter));
  81. }
  82. watch.Stop();
  83. Trace.WriteLine(String.Format("Total time: {0} milliseconds", watch.ElapsedMilliseconds));
  84. }
  85. }
  86. [Test]
  87. public void TestGpuMatContinuous()
  88. {
  89. if (!CudaInvoke.HasCuda)
  90. return;
  91. GpuMat<Byte> mat = new GpuMat<byte>(1200, 640, 1, true);
  92. Assert.IsTrue(mat.IsContinuous);
  93. }
  94. [Test]
  95. public void TestGpuMatRange()
  96. {
  97. if (CudaInvoke.HasCuda)
  98. {
  99. Image<Gray, Byte> img1 = new Image<Gray, byte>(1200, 640);
  100. img1.SetRandUniform(new MCvScalar(0, 0, 0), new MCvScalar(255, 255, 255));
  101. using (GpuMat gpuImg1 = new GpuMat(img1))
  102. using (GpuMat mat = new GpuMat(gpuImg1, new Emgu.CV.Structure.Range(0, 1), Emgu.CV.Structure.Range.All))
  103. {
  104. Size s = mat.Size;
  105. }
  106. }
  107. }
  108. [Test]
  109. public void TestGpuMatAdd()
  110. {
  111. if (CudaInvoke.HasCuda)
  112. {
  113. int repeat = 1000;
  114. Image<Gray, Byte> img1 = new Image<Gray, byte>(1200, 640);
  115. Image<Gray, Byte> img2 = new Image<Gray, byte>(img1.Size);
  116. img1.SetRandUniform(new MCvScalar(0, 0, 0), new MCvScalar(255, 255, 255));
  117. img2.SetRandUniform(new MCvScalar(0, 0, 0), new MCvScalar(255, 255, 255));
  118. Image<Gray, Byte> cpuImgSum = new Image<Gray, byte>(img1.Size);
  119. Stopwatch watch = Stopwatch.StartNew();
  120. for (int i = 0; i < repeat; i++)
  121. CvInvoke.Add(img1, img2, cpuImgSum, null, CvEnum.DepthType.Cv8U);
  122. watch.Stop();
  123. Trace.WriteLine(
  124. String.Format("CPU processing time: {0}ms", (double)watch.ElapsedMilliseconds / repeat));
  125. watch.Reset();
  126. watch.Start();
  127. CudaImage<Gray, Byte> gpuImg1 = new CudaImage<Gray, byte>(img1);
  128. CudaImage<Gray, Byte> gpuImg2 = new CudaImage<Gray, byte>(img2);
  129. CudaImage<Gray, Byte> gpuImgSum = new CudaImage<Gray, byte>(gpuImg1.Size);
  130. Stopwatch watch2 = Stopwatch.StartNew();
  131. for (int i = 0; i < repeat; i++)
  132. CudaInvoke.Add(gpuImg1, gpuImg2, gpuImgSum);
  133. watch2.Stop();
  134. Image<Gray, Byte> cpuImgSumFromGpu = gpuImgSum.ToImage();
  135. watch.Stop();
  136. Trace.WriteLine(String.Format("Core GPU processing time: {0}ms",
  137. (double)watch2.ElapsedMilliseconds / repeat));
  138. //Trace.WriteLine(String.Format("Total GPU processing time: {0}ms", (double)watch.ElapsedMilliseconds/repeat));
  139. Assert.IsTrue(cpuImgSum.Equals(cpuImgSumFromGpu));
  140. }
  141. }
  142. [Test]
  143. public void TestSplitMerge()
  144. {
  145. if (CudaInvoke.HasCuda)
  146. {
  147. using (Image<Bgr, Byte> img1 = new Image<Bgr, byte>(1200, 640))
  148. {
  149. img1.SetRandUniform(new MCvScalar(0, 0, 0), new MCvScalar(255, 255, 255));
  150. using (GpuMat gpuImg1 = new GpuMat(img1))
  151. {
  152. GpuMat[] channels = gpuImg1.Split(null);
  153. for (int i = 0; i < channels.Length; i++)
  154. {
  155. Mat imgL = channels[i].ToMat();
  156. Image<Gray, Byte> imgR = img1[i];
  157. Assert.IsTrue(imgL.Equals(imgR.Mat), "failed split GpuMat");
  158. }
  159. using (GpuMat gpuImg2 = new GpuMat())
  160. {
  161. gpuImg2.MergeFrom(channels, null);
  162. using (Image<Bgr, byte> img2 = new Image<Bgr, byte>(img1.Size))
  163. {
  164. gpuImg2.Download(img2);
  165. Assert.IsTrue(img2.Equals(img1), "failed split and merge test");
  166. }
  167. }
  168. for (int i = 0; i < channels.Length; i++)
  169. {
  170. channels[i].Dispose();
  171. }
  172. }
  173. }
  174. }
  175. }
  176. [Test]
  177. public void TestCudaFlip()
  178. {
  179. if (CudaInvoke.HasCuda)
  180. {
  181. using (Image<Bgr, Byte> img1 = new Image<Bgr, byte>(1200, 640))
  182. {
  183. img1.SetRandUniform(new MCvScalar(0, 0, 0), new MCvScalar(255, 255, 255));
  184. using (Image<Bgr, Byte> img1Flip = img1.Flip(CvEnum.FlipType.Horizontal | CvEnum.FlipType.Vertical))
  185. using (CudaImage<Bgr, Byte> cudaImage = new CudaImage<Bgr, byte>(img1))
  186. using (CudaImage<Bgr, Byte> cudaFlip = new CudaImage<Bgr, byte>(img1.Size))
  187. {
  188. CudaInvoke.Flip(cudaImage, cudaFlip, CvEnum.FlipType.Horizontal | CvEnum.FlipType.Vertical,
  189. null);
  190. cudaFlip.Download(img1);
  191. Assert.IsTrue(img1.Equals(img1Flip));
  192. }
  193. }
  194. }
  195. }
  196. [Test]
  197. public void TestConvolutionAndLaplace()
  198. {
  199. if (CudaInvoke.HasCuda)
  200. {
  201. Image<Gray, Byte> image = new Image<Gray, byte>(300, 400);
  202. image.SetRandUniform(new MCvScalar(0.0), new MCvScalar(255.0));
  203. float[,] k =
  204. {
  205. {0, 1, 0},
  206. {1, -4, 1},
  207. {0, 1, 0}
  208. };
  209. using (ConvolutionKernelF kernel = new ConvolutionKernelF(k))
  210. using (Stream s = new Stream())
  211. using (GpuMat cudaImg = new GpuMat(image))
  212. using (GpuMat cudaLaplace = new GpuMat())
  213. using (CudaLinearFilter cudaLinear =
  214. new CudaLinearFilter(DepthType.Cv8U, 1, DepthType.Cv8U, 1, kernel, kernel.Center))
  215. using (GpuMat cudaConv = new GpuMat())
  216. using (CudaLaplacianFilter laplacian =
  217. new CudaLaplacianFilter(DepthType.Cv8U, 1, DepthType.Cv8U, 1, 1, 1.0))
  218. {
  219. cudaLinear.Apply(cudaImg, cudaConv, s);
  220. laplacian.Apply(cudaImg, cudaLaplace, s);
  221. s.WaitForCompletion();
  222. Assert.IsTrue(cudaLaplace.Equals(cudaConv));
  223. }
  224. }
  225. }
  226. [Test]
  227. public void TestCudaFilters()
  228. {
  229. if (CudaInvoke.HasCuda)
  230. {
  231. Image<Gray, Byte> image = new Image<Gray, byte>(300, 400);
  232. image.SetRandUniform(new MCvScalar(0.0), new MCvScalar(255.0));
  233. using (GpuMat cudaImg1 = new GpuMat(image))
  234. using (GpuMat cudaImg2 = new GpuMat())
  235. using (CudaGaussianFilter gaussian = new CudaGaussianFilter(DepthType.Cv8U, 1, DepthType.Cv8U, 1,
  236. new Size(5, 5), 0, 0, CvEnum.BorderType.Default, CvEnum.BorderType.Default))
  237. using (CudaSobelFilter sobel = new CudaSobelFilter(DepthType.Cv8U, 1, DepthType.Cv8U, 1, 1, 1, 3, 1.0,
  238. CvEnum.BorderType.Default, CvEnum.BorderType.Default))
  239. {
  240. gaussian.Apply(cudaImg1, cudaImg2, null);
  241. sobel.Apply(cudaImg1, cudaImg2, null);
  242. }
  243. }
  244. }
  245. [Test]
  246. public void TestResizeGray()
  247. {
  248. if (CudaInvoke.HasCuda)
  249. {
  250. Image<Gray, Byte> img = new Image<Gray, byte>(300, 400);
  251. img.SetRandUniform(new MCvScalar(0.0), new MCvScalar(255.0));
  252. //Image<Gray, Byte> img = new Image<Gray, byte>("airplane.jpg");
  253. Image<Gray, Byte> small = img.Resize(100, 200, Emgu.CV.CvEnum.Inter.Linear);
  254. CudaImage<Gray, Byte> gpuImg = new CudaImage<Gray, byte>(img);
  255. CudaImage<Gray, byte> smallGpuImg = new CudaImage<Gray, byte>(small.Size);
  256. CudaInvoke.Resize(gpuImg, smallGpuImg, small.Size);
  257. Image<Gray, Byte> diff = smallGpuImg.ToImage().AbsDiff(small);
  258. //ImageViewer.Show(smallGpuImg.ToImage());
  259. //ImageViewer.Show(small);
  260. //Assert.IsTrue(smallGpuImg.ToImage().Equals(small));
  261. }
  262. }
  263. [Test]
  264. public void TestClone()
  265. {
  266. if (CudaInvoke.HasCuda)
  267. {
  268. Image<Gray, Byte> img = new Image<Gray, byte>(300, 400);
  269. img.SetRandUniform(new MCvScalar(0.0), new MCvScalar(255.0));
  270. using (CudaImage<Gray, Byte> gImg1 = new CudaImage<Gray, byte>(img))
  271. using (CudaImage<Gray, Byte> gImg2 = gImg1.Clone(null))
  272. using (Image<Gray, Byte> img2 = gImg2.ToImage())
  273. {
  274. Assert.IsTrue(img.Equals(img2));
  275. }
  276. }
  277. }
  278. [Test]
  279. public void TestColorConvert()
  280. {
  281. if (CudaInvoke.HasCuda)
  282. {
  283. Image<Bgr, Byte> img = new Image<Bgr, byte>(300, 400);
  284. img.SetRandUniform(new MCvScalar(0.0, 0.0, 0.0), new MCvScalar(255.0, 255.0, 255.0));
  285. Image<Gray, Byte> imgGray = img.Convert<Gray, Byte>();
  286. Image<Hsv, Byte> imgHsv = img.Convert<Hsv, Byte>();
  287. CudaImage<Bgr, Byte> gpuImg = new CudaImage<Bgr, Byte>(img);
  288. CudaImage<Gray, Byte> gpuImgGray = gpuImg.Convert<Gray, Byte>();
  289. CudaImage<Hsv, Byte> gpuImgHsv = gpuImg.Convert<Hsv, Byte>();
  290. Assert.IsTrue(gpuImgGray.Equals(new CudaImage<Gray, Byte>(imgGray)));
  291. Assert.IsTrue(gpuImgHsv.ToImage().Equals(imgHsv));
  292. Assert.IsTrue(gpuImgHsv.Equals(new CudaImage<Hsv, Byte>(imgHsv)));
  293. }
  294. }
  295. [Test]
  296. public void TestInplaceNot()
  297. {
  298. if (CudaInvoke.HasCuda)
  299. {
  300. Image<Bgr, Byte> img = new Image<Bgr, byte>(300, 400);
  301. CudaImage<Bgr, Byte> gpuMat = new CudaImage<Bgr, byte>(img);
  302. CudaInvoke.BitwiseNot(gpuMat, gpuMat, null, null);
  303. Assert.IsTrue(gpuMat.Equals(new CudaImage<Bgr, Byte>(img.Not())));
  304. }
  305. }
  306. [Test]
  307. public void TestResizeBgr()
  308. {
  309. if (CudaInvoke.HasCuda)
  310. {
  311. Image<Bgr, Byte> img = new Image<Bgr, byte>("pedestrian.png");
  312. //img.SetRandUniform(new MCvScalar(0.0, 0.0, 0.0), new MCvScalar(255.0, 255.0, 255.0));
  313. Size size = new Size(100, 200);
  314. CudaImage<Bgr, Byte> cudaImg = new CudaImage<Bgr, byte>(img);
  315. CudaImage<Bgr, byte> smallCudaImg = new CudaImage<Bgr, byte>(size);
  316. CudaInvoke.Resize(cudaImg, smallCudaImg, size);
  317. Image<Bgr, Byte> smallCpuImg = img.Resize(size.Width, size.Height, Emgu.CV.CvEnum.Inter.Linear);
  318. Image<Bgr, Byte> diff = smallCudaImg.ToImage().AbsDiff(smallCpuImg);
  319. //TODO: Check why they are not an exact match
  320. //Assert.IsTrue(diff.CountNonzero()[0] == 0);
  321. //ImageViewer.Show(smallGpuImg.ToImage());
  322. //ImageViewer.Show(small);
  323. }
  324. }
  325. [Test]
  326. public void TestCanny()
  327. {
  328. if (CudaInvoke.HasCuda)
  329. {
  330. using (Image<Bgr, Byte> image = new Image<Bgr, byte>("pedestrian.png"))
  331. using (CudaImage<Bgr, Byte> cudaImage = new CudaImage<Bgr, byte>(image))
  332. using (CudaImage<Gray, Byte> gray = cudaImage.Convert<Gray, Byte>())
  333. using (CudaImage<Gray, Byte> canny = new CudaImage<Gray, byte>(gray.Size))
  334. using (CudaCannyEdgeDetector detector = new CudaCannyEdgeDetector(20, 100, 3, false))
  335. {
  336. detector.Detect(gray, canny);
  337. //GpuInvoke.Canny(gray, canny, 20, 100, 3, false);
  338. //ImageViewer.Show(canny);
  339. }
  340. }
  341. }
  342. [Test]
  343. public void TestCountNonZero()
  344. {
  345. if (!CudaInvoke.HasCuda)
  346. return;
  347. //Mat m = new Mat(100, 200, Mat.Depth.Cv8U, 1);
  348. CudaImage<Gray, Byte> m = new CudaImage<Gray, Byte>(100, 200);
  349. m.SetTo(new MCvScalar(), null, null);
  350. EmguAssert.IsTrue(0 == CudaInvoke.CountNonZero(m));
  351. //Trace.WriteLine(String.Format("non zero count: {0}", ));
  352. }
  353. [Test]
  354. public void TestClahe()
  355. {
  356. if (CudaInvoke.HasCuda)
  357. {
  358. Image<Gray, Byte> image = EmguAssert.LoadImage<Gray, Byte>("pedestrian.png");
  359. CudaImage<Gray, Byte> cudaImage = new CudaImage<Gray, byte>(image);
  360. CudaImage<Gray, Byte> cudaResult = new CudaImage<Gray, byte>(cudaImage.Size);
  361. using (CudaClahe clahe = new CudaClahe(40.0, new Size(8, 8)))
  362. {
  363. Image<Gray, Byte> result = new Image<Gray, byte>(cudaResult.Size);
  364. clahe.Apply(cudaImage, cudaResult, null);
  365. cudaResult.Download(result);
  366. //Emgu.CV.UI.ImageViewer.Show(image.ConcateHorizontal(result));
  367. }
  368. }
  369. }
  370. [Test]
  371. public void TestHOG1()
  372. {
  373. if (CudaInvoke.HasCuda)
  374. {
  375. using (CudaHOG hog = new CudaHOG(new Size(64, 128), new Size(16, 16), new Size(8, 8), new Size(8, 8),
  376. 9))
  377. using (Mat pedestrianDescriptor = hog.GetDefaultPeopleDetector())
  378. using (Image<Bgr, Byte> image = new Image<Bgr, byte>("pedestrian.png"))
  379. {
  380. hog.SetSVMDetector(pedestrianDescriptor);
  381. //hog.GroupThreshold = 0;
  382. Stopwatch watch = Stopwatch.StartNew();
  383. Rectangle[] rects;
  384. using (CudaImage<Bgr, Byte> CudaImage = new CudaImage<Bgr, byte>(image))
  385. using (CudaImage<Bgra, Byte> gpuBgra = CudaImage.Convert<Bgra, Byte>())
  386. using (VectorOfRect vRect = new VectorOfRect())
  387. {
  388. hog.DetectMultiScale(gpuBgra, vRect);
  389. rects = vRect.ToArray();
  390. }
  391. watch.Stop();
  392. Assert.AreEqual(1, rects.Length);
  393. foreach (Rectangle rect in rects)
  394. image.Draw(rect, new Bgr(Color.Red), 1);
  395. Trace.WriteLine(String.Format("HOG detection time: {0} ms", watch.ElapsedMilliseconds));
  396. //ImageViewer.Show(image, String.Format("Detection Time: {0}ms", watch.ElapsedMilliseconds));
  397. }
  398. }
  399. }
  400. [Test]
  401. public void TestHOG2()
  402. {
  403. if (CudaInvoke.HasCuda)
  404. {
  405. using (CudaHOG hog = new CudaHOG(
  406. new Size(48, 96), //winSize
  407. new Size(16, 16), //blockSize
  408. new Size(8, 8), //blockStride
  409. new Size(8, 8) //cellSize
  410. ))
  411. using (Mat pedestrianDescriptor = hog.GetDefaultPeopleDetector())
  412. using (Image<Bgr, Byte> image = new Image<Bgr, byte>("pedestrian.png"))
  413. {
  414. //float[] pedestrianDescriptor = CudaHOGDescriptor.GetPeopleDetector48x96();
  415. hog.SetSVMDetector(pedestrianDescriptor);
  416. Stopwatch watch = Stopwatch.StartNew();
  417. Rectangle[] rects;
  418. using (GpuMat cudaImage = new GpuMat(image))
  419. using (GpuMat gpuBgra = new GpuMat())
  420. using (VectorOfRect vRect = new VectorOfRect())
  421. {
  422. CudaInvoke.CvtColor(cudaImage, gpuBgra, ColorConversion.Bgr2Bgra);
  423. hog.DetectMultiScale(gpuBgra, vRect);
  424. rects = vRect.ToArray();
  425. }
  426. watch.Stop();
  427. //Assert.AreEqual(1, rects.Length);
  428. foreach (Rectangle rect in rects)
  429. image.Draw(rect, new Bgr(Color.Red), 1);
  430. Trace.WriteLine(String.Format("HOG detection time: {0} ms", watch.ElapsedMilliseconds));
  431. //ImageViewer.Show(image, String.Format("Detection Time: {0}ms", watch.ElapsedMilliseconds));
  432. }
  433. }
  434. }
  435. [Test]
  436. public void TestCudaReduce()
  437. {
  438. if (!CudaInvoke.HasCuda)
  439. return;
  440. using (Image<Bgr, Byte> img = new Image<Bgr, byte>(480, 320))
  441. {
  442. img.SetRandUniform(new MCvScalar(0, 0, 0), new MCvScalar(255, 255, 255));
  443. using (GpuMat cudaImage = new GpuMat(img))
  444. using (GpuMat reduced = new GpuMat())
  445. {
  446. CudaInvoke.Reduce(cudaImage, reduced, CvEnum.ReduceDimension.SingleRow,
  447. CvEnum.ReduceType.ReduceAvg);
  448. }
  449. }
  450. }
  451. [Test]
  452. public void TestErodeDilate()
  453. {
  454. if (!CudaInvoke.HasCuda)
  455. return;
  456. int morphIter = 2;
  457. Image<Gray, Byte> image = new Image<Gray, byte>(640, 320);
  458. image.Draw(new CircleF(new PointF(200, 200), 30), new Gray(255.0), 4);
  459. Size ksize = new Size(morphIter * 2 + 1, morphIter * 2 + 1);
  460. using (GpuMat cudaImage = new GpuMat(image))
  461. using (GpuMat cudaTemp = new GpuMat())
  462. using (Stream stream = new Stream())
  463. using (CudaBoxMaxFilter dilate = new CudaBoxMaxFilter(DepthType.Cv8U, 1, ksize, new Point(-1, -1),
  464. CvEnum.BorderType.Default, new MCvScalar()))
  465. using (CudaBoxMinFilter erode = new CudaBoxMinFilter(DepthType.Cv8U, 1, ksize, new Point(-1, -1),
  466. CvEnum.BorderType.Default, new MCvScalar()))
  467. {
  468. //run the GPU version asyncrhonously with stream
  469. erode.Apply(cudaImage, cudaTemp, stream);
  470. dilate.Apply(cudaTemp, cudaImage, stream);
  471. //run the CPU version in parallel to the gpu version.
  472. using (Image<Gray, Byte> temp = new Image<Gray, byte>(image.Size))
  473. {
  474. CvInvoke.Erode(image, temp, null, new Point(-1, -1), morphIter, CvEnum.BorderType.Constant,
  475. new MCvScalar());
  476. CvInvoke.Dilate(temp, image, null, new Point(-1, -1), morphIter, CvEnum.BorderType.Constant,
  477. new MCvScalar());
  478. }
  479. //syncrhonize with the GPU version
  480. stream.WaitForCompletion();
  481. Assert.IsTrue(cudaImage.ToMat().Equals(image.Mat));
  482. }
  483. }
  484. #if NONFREE
  485. [Test]
  486. public void TestCudaSURFKeypointDetection()
  487. {
  488. if (CudaInvoke.HasCuda)
  489. {
  490. Image<Gray, byte> image = new Image<Gray, byte>(200, 100);
  491. image.SetRandUniform(new MCvScalar(), new MCvScalar(255));
  492. GpuMat gpuMat = new GpuMat(image);
  493. EmguAssert.IsTrue(gpuMat.ToMat().Equals(image.Mat));
  494. CudaSURF cudaSurf = new CudaSURF(100.0f, 2, 4, false, 0.01f, false);
  495. GpuMat cudaKpts = cudaSurf.DetectKeyPointsRaw(gpuMat, null);
  496. VectorOfKeyPoint kpts = new VectorOfKeyPoint();
  497. cudaSurf.DownloadKeypoints(cudaKpts, kpts);
  498. }
  499. }
  500. #endif
  501. [Test]
  502. public void TestCudaFASTDetector()
  503. {
  504. if (!CudaInvoke.HasCuda)
  505. return;
  506. using (Image<Bgr, Byte> img = new Image<Bgr, byte>("box.png"))
  507. using (CudaImage<Bgr, Byte> CudaImage = new CudaImage<Bgr, byte>(img))
  508. using (CudaImage<Gray, Byte> grayCudaImage = CudaImage.Convert<Gray, Byte>())
  509. using (CudaFastFeatureDetector featureDetector =
  510. new CudaFastFeatureDetector(10, true, FastFeatureDetector.DetectorType.Type9_16, 1000))
  511. using (VectorOfKeyPoint kpts = new VectorOfKeyPoint())
  512. using (GpuMat keyPointsMat = new GpuMat())
  513. {
  514. featureDetector.DetectAsync(grayCudaImage, keyPointsMat);
  515. featureDetector.Convert(keyPointsMat, kpts);
  516. //featureDetector.DetectKeyPointsRaw(grayCudaImage, null, keyPointsMat);
  517. //featureDetector.DownloadKeypoints(keyPointsMat, kpts);
  518. foreach (MKeyPoint kpt in kpts.ToArray())
  519. {
  520. img.Draw(new CircleF(kpt.Point, 3.0f), new Bgr(0, 255, 0), 1);
  521. }
  522. //ImageViewer.Show(img);
  523. }
  524. }
  525. [Test]
  526. public void TestCudaOrbDetector()
  527. {
  528. if (!CudaInvoke.HasCuda)
  529. return;
  530. using (Image<Bgr, Byte> img = new Image<Bgr, byte>("box.png"))
  531. using (GpuMat cudaImage = new GpuMat(img))
  532. using (GpuMat grayCudaImage = new GpuMat())
  533. using (CudaORBDetector detector = new CudaORBDetector(500))
  534. using (VectorOfKeyPoint kpts = new VectorOfKeyPoint())
  535. using (GpuMat keyPointMat = new GpuMat())
  536. using (GpuMat descriptorMat = new GpuMat())
  537. {
  538. CudaInvoke.CvtColor(cudaImage, grayCudaImage, ColorConversion.Bgr2Gray);
  539. //Async version
  540. detector.DetectAsync(grayCudaImage, keyPointMat);
  541. detector.Convert(keyPointMat, kpts);
  542. foreach (MKeyPoint kpt in kpts.ToArray())
  543. {
  544. img.Draw(new CircleF(kpt.Point, 3.0f), new Bgr(0, 255, 0), 1);
  545. }
  546. //sync version
  547. detector.DetectRaw(grayCudaImage, kpts);
  548. //ImageViewer.Show(img);
  549. }
  550. }
  551. [Test]
  552. public void TestCudaPyr()
  553. {
  554. if (!CudaInvoke.HasCuda)
  555. return;
  556. Image<Gray, Byte> img = new Image<Gray, byte>(640, 480);
  557. img.SetRandUniform(new MCvScalar(), new MCvScalar(255, 255, 255));
  558. Image<Gray, Byte> down = img.PyrDown();
  559. Image<Gray, Byte> up = down.PyrUp();
  560. CudaImage<Gray, Byte> gImg = new CudaImage<Gray, byte>(img);
  561. CudaImage<Gray, Byte> gDown = new CudaImage<Gray, byte>(img.Size.Width >> 1, img.Size.Height >> 1);
  562. CudaImage<Gray, Byte> gUp = new CudaImage<Gray, byte>(img.Size);
  563. CudaInvoke.PyrDown(gImg, gDown, null);
  564. CudaInvoke.PyrUp(gDown, gUp, null);
  565. CvInvoke.AbsDiff(down, gDown.ToImage(), down);
  566. CvInvoke.AbsDiff(up, gUp.ToImage(), up);
  567. double[] minVals, maxVals;
  568. Point[] minLocs, maxLocs;
  569. down.MinMax(out minVals, out maxVals, out minLocs, out maxLocs);
  570. double maxVal = 0.0;
  571. for (int i = 0; i < maxVals.Length; i++)
  572. {
  573. if (maxVals[i] > maxVal)
  574. maxVal = maxVals[i];
  575. }
  576. Trace.WriteLine(String.Format("Max diff: {0}", maxVal));
  577. EmguAssert.IsTrue(maxVal <= 1.0);
  578. //Assert.LessOrEqual(maxVal, 1.0);
  579. up.MinMax(out minVals, out maxVals, out minLocs, out maxLocs);
  580. maxVal = 0.0;
  581. for (int i = 0; i < maxVals.Length; i++)
  582. {
  583. if (maxVals[i] > maxVal)
  584. maxVal = maxVals[i];
  585. }
  586. Trace.WriteLine(String.Format("Max diff: {0}", maxVal));
  587. EmguAssert.IsTrue(maxVal <= 1.0);
  588. //Assert.LessOrEqual(maxVal, 1.0);
  589. }
  590. [Test]
  591. public void TestMatchTemplate()
  592. {
  593. if (!CudaInvoke.HasCuda)
  594. return;
  595. #region prepare synthetic image for testing
  596. int templWidth = 50;
  597. int templHeight = 50;
  598. Point templCenter = new Point(120, 100);
  599. //Create a random object
  600. Image<Bgr, Byte> randomObj = new Image<Bgr, byte>(templWidth, templHeight);
  601. randomObj.SetRandUniform(new MCvScalar(), new MCvScalar(255, 255, 255));
  602. //Draw the object in image1 center at templCenter;
  603. Image<Bgr, Byte> img = new Image<Bgr, byte>(300, 200);
  604. Rectangle objectLocation = new Rectangle(templCenter.X - (templWidth >> 1),
  605. templCenter.Y - (templHeight >> 1), templWidth, templHeight);
  606. img.ROI = objectLocation;
  607. randomObj.Copy(img, null);
  608. img.ROI = Rectangle.Empty;
  609. #endregion
  610. Image<Gray, Single> match = img.MatchTemplate(randomObj, Emgu.CV.CvEnum.TemplateMatchingType.Sqdiff);
  611. double[] minVal, maxVal;
  612. Point[] minLoc, maxLoc;
  613. match.MinMax(out minVal, out maxVal, out minLoc, out maxLoc);
  614. double gpuMinVal = 0, gpuMaxVal = 0;
  615. Point gpuMinLoc = Point.Empty, gpuMaxLoc = Point.Empty;
  616. GpuMat cudaImage = new GpuMat(img);
  617. GpuMat gpuRandomObj = new GpuMat(randomObj);
  618. GpuMat gpuMatch = new GpuMat();
  619. using (CudaTemplateMatching buffer =
  620. new CudaTemplateMatching(DepthType.Cv8U, 3, CvEnum.TemplateMatchingType.Sqdiff))
  621. using (Stream stream = new Stream())
  622. {
  623. buffer.Match(cudaImage, gpuRandomObj, gpuMatch, stream);
  624. //GpuInvoke.MatchTemplate(CudaImage, gpuRandomObj, gpuMatch, CvEnum.TM_TYPE.CV_TM_SQDIFF, buffer, stream);
  625. stream.WaitForCompletion();
  626. CudaInvoke.MinMaxLoc(gpuMatch, ref gpuMinVal, ref gpuMaxVal, ref gpuMinLoc, ref gpuMaxLoc, null);
  627. }
  628. EmguAssert.AreEqual(minLoc[0].X, templCenter.X - templWidth / 2);
  629. EmguAssert.AreEqual(minLoc[0].Y, templCenter.Y - templHeight / 2);
  630. EmguAssert.IsTrue(minLoc[0].Equals(gpuMinLoc));
  631. EmguAssert.IsTrue(maxLoc[0].Equals(gpuMaxLoc));
  632. }
  633. [Test]
  634. public void TestCudaRemap()
  635. {
  636. if (!CudaInvoke.HasCuda)
  637. return;
  638. Image<Gray, float> xmap = new Image<Gray, float>(2, 2);
  639. xmap.Data[0, 0, 0] = 0;
  640. xmap.Data[0, 1, 0] = 0;
  641. xmap.Data[1, 0, 0] = 1;
  642. xmap.Data[1, 1, 0] = 1;
  643. Image<Gray, float> ymap = new Image<Gray, float>(2, 2);
  644. ymap.Data[0, 0, 0] = 0;
  645. ymap.Data[0, 1, 0] = 1;
  646. ymap.Data[1, 0, 0] = 0;
  647. ymap.Data[1, 1, 0] = 1;
  648. Image<Gray, Byte> image = new Image<Gray, byte>(2, 2);
  649. image.SetRandNormal(new MCvScalar(), new MCvScalar(255));
  650. using (CudaImage<Gray, Byte> CudaImage = new CudaImage<Gray, byte>(image))
  651. using (CudaImage<Gray, float> xCudaImage = new CudaImage<Gray, float>(xmap))
  652. using (CudaImage<Gray, float> yCudaImage = new CudaImage<Gray, float>(ymap))
  653. using (CudaImage<Gray, Byte> remapedImage = new CudaImage<Gray, byte>(CudaImage.Size))
  654. {
  655. CudaInvoke.Remap(CudaImage, remapedImage, xCudaImage, yCudaImage, CvEnum.Inter.Cubic,
  656. CvEnum.BorderType.Default, new MCvScalar(), null);
  657. }
  658. }
  659. [Test]
  660. public void TestCudaWarpPerspective()
  661. {
  662. if (!CudaInvoke.HasCuda)
  663. return;
  664. Matrix<float> transformation = new Matrix<float>(3, 3);
  665. transformation.SetIdentity();
  666. Image<Gray, byte> image = new Image<Gray, byte>(480, 320);
  667. image.SetRandNormal(new MCvScalar(), new MCvScalar(255));
  668. using (GpuMat cudaImage = new GpuMat(image))
  669. using (CudaImage<Gray, Byte> resultCudaImage = new CudaImage<Gray, byte>())
  670. {
  671. CudaInvoke.WarpPerspective(cudaImage, resultCudaImage, transformation, cudaImage.Size,
  672. CvEnum.Inter.Cubic, CvEnum.BorderType.Default, new MCvScalar(), null);
  673. }
  674. }
  675. [Test]
  676. public void TestCudaPyrLKOpticalFlow()
  677. {
  678. if (!CudaInvoke.HasCuda)
  679. return;
  680. //Image<Gray, Byte> prevImg, currImg;
  681. //AutoTestVarious.OpticalFlowImage(out prevImg, out currImg);
  682. GpuMat[] images = OpticalFlowImage();
  683. Mat flow = new Mat();
  684. using (CudaDensePyrLKOpticalFlow opticalflow = new CudaDensePyrLKOpticalFlow(new Size(21, 21), 3, 30, false)
  685. )
  686. using (CudaSparsePyrLKOpticalFlow opticalFlowSparse = new CudaSparsePyrLKOpticalFlow(new Size(21, 21)))
  687. //using (CudaImage<Gray, Byte> prevGpu = new CudaImage<Gray, byte>(prevImg))
  688. //using (CudaImage<Gray, byte> currGpu = new CudaImage<Gray, byte>(currImg))
  689. using (GpuMat flowGpu = new GpuMat())
  690. using (VectorOfPointF prevPts = new VectorOfPointF())
  691. using (GpuMat currPtrsGpu = new GpuMat())
  692. using (GpuMat statusGpu = new GpuMat())
  693. {
  694. opticalflow.Calc(images[0], images[1], flowGpu);
  695. flowGpu.Download(flow);
  696. int pointsCount = 100;
  697. Size s = images[0].Size;
  698. PointF[] points = new PointF[pointsCount];
  699. Random r = new Random(1234);
  700. for (int i = 0; i < points.Length; i++)
  701. {
  702. points[i] = new PointF(r.Next(s.Height), r.Next(s.Width));
  703. }
  704. prevPts.Push(points);
  705. using (GpuMat prevPtsGpu = new GpuMat(prevPts))
  706. opticalFlowSparse.Calc(images[0], images[1], prevPtsGpu, currPtrsGpu, statusGpu);
  707. }
  708. for (int i = 0; i < images.Length; i++)
  709. images[i].Dispose();
  710. }
  711. [Test]
  712. public void TestCudaUploadDownload()
  713. {
  714. if (!CudaInvoke.HasCuda)
  715. return;
  716. Mat m = new Mat(new Size(480, 320), DepthType.Cv8U, 3);
  717. CvInvoke.Randu(m, new MCvScalar(), new MCvScalar(255, 255, 255));
  718. #region test for async download & upload
  719. Stream stream = new Stream();
  720. GpuMat gm1 = new GpuMat();
  721. gm1.Upload(m, stream);
  722. Mat m2 = new Mat();
  723. gm1.Download(m2, stream);
  724. stream.WaitForCompletion();
  725. EmguAssert.IsTrue(m.Equals(m2));
  726. #endregion
  727. #region test for blocking download & upload
  728. GpuMat gm2 = new GpuMat();
  729. gm2.Upload(m);
  730. Mat m3 = new Mat();
  731. gm2.Download(m3);
  732. EmguAssert.IsTrue(m.Equals(m3));
  733. #endregion
  734. }
  735. [Test]
  736. public void TestCudaBroxOpticalFlow()
  737. {
  738. if (!CudaInvoke.HasCuda)
  739. return;
  740. //Image<Gray, Byte> prevImg, currImg;
  741. //AutoTestVarious.OpticalFlowImage(out prevImg, out currImg);
  742. GpuMat[] images = OpticalFlowImage();
  743. Mat flow = new Mat();
  744. CudaBroxOpticalFlow opticalflow = new CudaBroxOpticalFlow();
  745. //using (CudaImage<Gray, float> prevGpu = new CudaImage<Gray, float>(prevImg.Convert<Gray, float>()))
  746. //using (CudaImage<Gray, float> currGpu = new CudaImage<Gray, float>(currImg.Convert<Gray, float>()))
  747. using (GpuMat flowGpu = new GpuMat())
  748. {
  749. opticalflow.Calc(images[0], images[1], flowGpu);
  750. flowGpu.Download(flow);
  751. }
  752. for (int i = 0; i < images.Length; i++)
  753. images[i].Dispose();
  754. }
  755. [Test]
  756. public void TestBilaterialFilter()
  757. {
  758. if (CudaInvoke.HasCuda)
  759. {
  760. Image<Bgr, Byte> img = new Image<Bgr, byte>("pedestrian.png");
  761. Image<Gray, byte> gray = img.Convert<Gray, Byte>();
  762. CudaImage<Gray, Byte> CudaImage = new CudaImage<Gray, byte>(gray);
  763. CudaImage<Gray, Byte> gpuBilaterial = new CudaImage<Gray, byte>(CudaImage.Size);
  764. CudaInvoke.BilateralFilter(CudaImage, gpuBilaterial, 7, 5, 5, CvEnum.BorderType.Default, null);
  765. //Emgu.CV.UI.ImageViewer.Show(gray.ConcateHorizontal(gpuBilaterial.ToImage()));
  766. }
  767. }
  768. #if CUDACODEC
  769. [Test]
  770. public void TestCudaVideoWriter()
  771. {
  772. if (CudaInvoke.HasCuda)
  773. {
  774. using (CudaVideoWriter writer = new CudaVideoWriter("cudavideo.avi", new Size(640, 480), 24))
  775. {
  776. using (GpuMat m1 = new GpuMat(480, 640, DepthType.Cv8U, 3))
  777. writer.Write(m1, false);
  778. using (GpuMat m2 = new GpuMat(480, 640, DepthType.Cv8U, 3))
  779. writer.Write(m2, true);
  780. }
  781. }
  782. }
  783. [Test]
  784. public void TestCudaVideoReader()
  785. {
  786. int numberOfFrames = 10;
  787. int width = 640;
  788. int height = 480;
  789. String fileName = AutoTestVarious.GetTempFileName() + ".avi";
  790. Image<Bgr, Byte>[] images = new Image<Bgr, byte>[numberOfFrames];
  791. for (int i = 0; i < images.Length; i++)
  792. {
  793. images[i] = new Image<Bgr, byte>(width, height);
  794. images[i].SetRandUniform(new MCvScalar(), new MCvScalar(255, 255, 255));
  795. }
  796. int fourcc = VideoWriter.Fourcc('M', 'J', 'P', 'G');
  797. Backend[] backends = CvInvoke.WriterBackends;
  798. int backend_idx = 0; //any backend;
  799. foreach (Backend be in backends)
  800. {
  801. if (be.Name.Equals("CV_MJPEG"))
  802. {
  803. backend_idx = be.ID;
  804. break;
  805. }
  806. }
  807. //using (VideoWriter writer = new VideoWriter(fileName, VideoWriter.Fourcc('H', '2', '6', '4'), 5, new Size(width, height), true))
  808. //using (VideoWriter writer = new VideoWriter(fileName, VideoWriter.Fourcc('M', 'J', 'P', 'G'), 5, new Size(width, height), true))
  809. //using (VideoWriter writer = new VideoWriter(fileName, VideoWriter.Fourcc('X', '2', '6', '4'), 5, new Size(width, height), true))
  810. //using (VideoWriter writer = new VideoWriter(fileName, -1, 5, new Size( width, height ), true))
  811. using (VideoWriter writer =
  812. new VideoWriter(fileName, backend_idx, fourcc, 24, new Size(width, height), true))
  813. {
  814. //EmguAssert.IsTrue(writer.IsOpened);
  815. for (int i = 0; i < numberOfFrames; i++)
  816. {
  817. writer.Write(images[i].Mat);
  818. }
  819. }
  820. FileInfo fi = new FileInfo(fileName);
  821. EmguAssert.IsTrue(fi.Exists && fi.Length != 0, "File should not be empty");
  822. using (CudaVideoReader reader = new CudaVideoReader(fileName))
  823. {
  824. var formatInfo = reader.Format;
  825. int count = 0;
  826. using (GpuMat frame = new GpuMat())
  827. while (reader.NextFrame(frame))
  828. {
  829. EmguAssert.IsTrue(frame.Size.Width == width);
  830. EmguAssert.IsTrue(frame.Size.Height == height);
  831. count++;
  832. }
  833. EmguAssert.IsTrue(numberOfFrames == count);
  834. }
  835. File.Delete(fi.FullName);
  836. }
  837. #endif
  838. /*
  839. [Test]
  840. public void TestSoftcascadeCuda()
  841. {
  842. if (CudaInvoke.HasCuda)
  843. {
  844. using (CudaDeviceInfo cdi = new CudaDeviceInfo())
  845. {
  846. using (CudaSoftCascadeDetector detector = new CudaSoftCascadeDetector(EmguAssert.GetFile("inria_caltech-17.01.2013.xml"), 0.4, 5.0, 55, SoftCascadeDetector.RejectionCriteria.Default))
  847. using (Image<Bgr, Byte> image = EmguAssert.LoadImage<Bgr, Byte>("pedestrian.png"))
  848. using (Cuda.CudaImage<Bgr, Byte> gImage = new CudaImage<Bgr, byte>(image))
  849. using (Matrix<int> rois = new Matrix<int>(1, 4))
  850. {
  851. Stopwatch watch = Stopwatch.StartNew();
  852. Size s = gImage.Size;
  853. rois.Data[0, 2] = s.Width;
  854. rois.Data[0, 3] = s.Height;
  855. using (GpuMat<int> gRois = new GpuMat<int>(rois))
  856. {
  857. Emgu.CV.Cuda.GpuMat result = detector.Detect(gImage, gRois, null);
  858. }
  859. watch.Stop();
  860. //foreach (SoftCascadeDetector.Detection detection in detections)
  861. // image.Draw(detection.BoundingBox, new Bgr(Color.Red), 1);
  862. //Emgu.CV.UI.ImageViewer.Show(image, String.Format("Detection Time: {0}ms", watch.ElapsedMilliseconds));
  863. }
  864. }
  865. }
  866. }*/
  867. [Test]
  868. public void TestGEMM()
  869. {
  870. if (CudaInvoke.HasCuda)
  871. {
  872. Mat a = new Mat(3, 3, DepthType.Cv32F, 1);
  873. Mat b = new Mat(3, 3, DepthType.Cv32F, 1);
  874. Mat c = new Mat(3, 3, DepthType.Cv32F, 1);
  875. Mat d = new Mat(3, 3, DepthType.Cv32F, 1);
  876. GpuMat ga = new GpuMat();
  877. GpuMat gb = new GpuMat();
  878. GpuMat gc = new GpuMat();
  879. GpuMat gd = new GpuMat();
  880. ga.Upload(a);
  881. gb.Upload(b);
  882. gc.Upload(c);
  883. gd.Upload(d);
  884. CvInvoke.Gemm(a, b, 1.0, c, 0.0, d);
  885. CudaInvoke.Gemm(ga, gb, 1.0, gc, 0.0, gd);
  886. }
  887. }
  888. [Test]
  889. public void TestHughCircle()
  890. {
  891. if (CudaInvoke.HasCuda)
  892. {
  893. Mat m = new Mat(480, 480, DepthType.Cv8U, 1);
  894. m.SetTo(new MCvScalar(0));
  895. CvInvoke.Circle(m, new Point(240, 240), 100, new MCvScalar(150), 10);
  896. GpuMat gm = new GpuMat();
  897. gm.Upload(m);
  898. using (CudaHoughCirclesDetector detector = new CudaHoughCirclesDetector(1, 30, 120, 30, 10, 400))
  899. using (GpuMat circlesGpu = new GpuMat())
  900. using (Mat circlesMat = new Mat())
  901. {
  902. detector.Detect(gm, circlesGpu);
  903. circlesGpu.Download(circlesMat);
  904. CircleF[] circles = new CircleF[circlesMat.Cols];
  905. GCHandle circlesHandle = GCHandle.Alloc(circles, GCHandleType.Pinned);
  906. Emgu.CV.Util.CvToolbox.Memcpy(circlesHandle.AddrOfPinnedObject(), circlesMat.DataPointer,
  907. Marshal.SizeOf(typeof(CircleF)) * circles.Length);
  908. circlesHandle.Free();
  909. foreach (var circle in circles)
  910. {
  911. CvInvoke.Circle(m, Point.Round(circle.Center), (int)circle.Radius, new MCvScalar(255));
  912. }
  913. }
  914. }
  915. }
  916. [Test]
  917. public void TestCudaHoughCircle()
  918. {
  919. if (CudaInvoke.HasCuda)
  920. {
  921. Mat m = new Mat(480, 480, DepthType.Cv8U, 1);
  922. m.SetTo(new MCvScalar(0));
  923. CvInvoke.Circle(m, new Point(240, 240), 100, new MCvScalar(150), 10);
  924. GpuMat gm = new GpuMat();
  925. gm.Upload(m);
  926. using (CudaHoughCirclesDetector detector = new CudaHoughCirclesDetector(1, 30, 120, 30, 10, 400))
  927. {
  928. CircleF[] circles = detector.Detect(gm);
  929. foreach (var circle in circles)
  930. {
  931. CvInvoke.Circle(m, Point.Round(circle.Center), (int)circle.Radius, new MCvScalar(255));
  932. }
  933. }
  934. }
  935. }
  936. [Test]
  937. public void TestBruteForceHammingDistance()
  938. {
  939. if (CudaInvoke.HasCuda)
  940. {
  941. Image<Gray, byte> box = new Image<Gray, byte>("box.png");
  942. FastFeatureDetector fast = new FastFeatureDetector(100, true);
  943. BriefDescriptorExtractor brief = new BriefDescriptorExtractor(32);
  944. #region extract features from the object image
  945. Stopwatch stopwatch = Stopwatch.StartNew();
  946. VectorOfKeyPoint modelKeypoints = new VectorOfKeyPoint();
  947. fast.DetectRaw(box, modelKeypoints);
  948. Mat modelDescriptors = new Mat();
  949. brief.Compute(box, modelKeypoints, modelDescriptors);
  950. stopwatch.Stop();
  951. Trace.WriteLine(String.Format("Time to extract feature from model: {0} milli-sec",
  952. stopwatch.ElapsedMilliseconds));
  953. #endregion
  954. Image<Gray, Byte> observedImage = new Image<Gray, byte>("box_in_scene.png");
  955. #region extract features from the observed image
  956. stopwatch.Reset();
  957. stopwatch.Start();
  958. VectorOfKeyPoint observedKeypoints = new VectorOfKeyPoint();
  959. fast.DetectRaw(observedImage, observedKeypoints);
  960. Mat observedDescriptors = new Mat();
  961. brief.Compute(observedImage, observedKeypoints, observedDescriptors);
  962. stopwatch.Stop();
  963. Trace.WriteLine(String.Format("Time to extract feature from image: {0} milli-sec",
  964. stopwatch.ElapsedMilliseconds));
  965. #endregion
  966. Mat homography = null;
  967. using (GpuMat<Byte> gpuModelDescriptors = new GpuMat<byte>(modelDescriptors)
  968. ) //initialization of GPU code might took longer time.
  969. {
  970. stopwatch.Reset();
  971. stopwatch.Start();
  972. CudaBFMatcher hammingMatcher = new CudaBFMatcher(DistanceType.Hamming);
  973. //BFMatcher hammingMatcher = new BFMatcher(BFMatcher.DistanceType.Hamming, modelDescriptors);
  974. int k = 2;
  975. Matrix<int> trainIdx = new Matrix<int>(observedKeypoints.Size, k);
  976. Matrix<float> distance = new Matrix<float>(trainIdx.Size);
  977. using (GpuMat<Byte> gpuObservedDescriptors = new GpuMat<byte>(observedDescriptors))
  978. //using (GpuMat<int> gpuTrainIdx = new GpuMat<int>(trainIdx.Rows, trainIdx.Cols, 1, true))
  979. //using (GpuMat<float> gpuDistance = new GpuMat<float>(distance.Rows, distance.Cols, 1, true))
  980. using (VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch())
  981. {
  982. Stopwatch w2 = Stopwatch.StartNew();
  983. //hammingMatcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, matches, k);
  984. hammingMatcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, matches, k, null, true);
  985. w2.Stop();
  986. Trace.WriteLine(String.Format(
  987. "Time for feature matching (excluding data transfer): {0} milli-sec",
  988. w2.ElapsedMilliseconds));
  989. //gpuTrainIdx.Download(trainIdx);
  990. //gpuDistance.Download(distance);
  991. Mat mask = new Mat(distance.Rows, 1, DepthType.Cv8U, 1);
  992. mask.SetTo(new MCvScalar(255));
  993. Features2DToolbox.VoteForUniqueness(matches, 0.8, mask);
  994. int nonZeroCount = CvInvoke.CountNonZero(mask);
  995. if (nonZeroCount >= 4)
  996. {
  997. nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeypoints,
  998. observedKeypoints,
  999. matches, mask, 1.5, 20);
  1000. if (nonZeroCount >= 4)
  1001. homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeypoints,
  1002. observedKeypoints, matches, mask, 2);
  1003. nonZeroCount = CvInvoke.CountNonZero(mask);
  1004. }
  1005. stopwatch.Stop();
  1006. Trace.WriteLine(String.Format(
  1007. "Time for feature matching (including data transfer): {0} milli-sec",
  1008. stopwatch.ElapsedMilliseconds));
  1009. }
  1010. }
  1011. if (homography != null)
  1012. {
  1013. Rectangle rect = box.ROI;
  1014. PointF[] pts = new PointF[]
  1015. {
  1016. new PointF(rect.Left, rect.Bottom),
  1017. new PointF(rect.Right, rect.Bottom),
  1018. new PointF(rect.Right, rect.Top),
  1019. new PointF(rect.Left, rect.Top)
  1020. };
  1021. PointF[] points = CvInvoke.PerspectiveTransform(pts, homography);
  1022. //homography.ProjectPoints(points);
  1023. //Merge the object image and the observed image into one big image for display
  1024. Image<Gray, Byte> res = box.ConcateVertical(observedImage);
  1025. for (int i = 0; i < points.Length; i++)
  1026. points[i].Y += box.Height;
  1027. res.DrawPolyline(Array.ConvertAll<PointF, Point>(points, Point.Round), true, new Gray(255.0), 5);
  1028. //ImageViewer.Show(res);
  1029. }
  1030. }
  1031. }
  1032. public GpuMat[] OpticalFlowImage()
  1033. {
  1034. Mat[] images = AutoTestVarious.OpticalFlowImage();
  1035. GpuMat[] gmats = new GpuMat[images.Length];
  1036. for (int i = 0; i < images.Length; i++)
  1037. {
  1038. GpuMat g = new GpuMat();
  1039. g.Upload(images[i]);
  1040. images[i].Dispose();
  1041. gmats[i] = g;
  1042. }
  1043. return gmats;
  1044. }
  1045. [Test]
  1046. public void TestNVidiaOpticalFlow_1_0()
  1047. {
  1048. if (!CudaInvoke.HasCuda)
  1049. return;
  1050. int cudaDevice = CudaInvoke.GetDevice();
  1051. using (CudaDeviceInfo deviceInfo = new CudaDeviceInfo(cudaDevice))
  1052. {
  1053. if (deviceInfo.CudaComputeCapability < new Version(7, 5))
  1054. return;
  1055. }
  1056. GpuMat[] images = OpticalFlowImage();
  1057. GpuMat result = new GpuMat();
  1058. Stopwatch watch = Stopwatch.StartNew();
  1059. NvidiaOpticalFlow_1_0 flow = new NvidiaOpticalFlow_1_0(images[0].Size);
  1060. flow.Calc(images[0], images[1], result);
  1061. watch.Stop();
  1062. EmguAssert.WriteLine(String.Format(
  1063. "Time: {0} milliseconds",
  1064. watch.ElapsedMilliseconds));
  1065. for (int i = 0; i < images.Length; i++)
  1066. {
  1067. images[i].Dispose();
  1068. }
  1069. }
  1070. [Test]
  1071. public void TestNVidiaOpticalFlow_2_0()
  1072. {
  1073. if (!CudaInvoke.HasCuda)
  1074. return;
  1075. int cudaDevice = CudaInvoke.GetDevice();
  1076. using (CudaDeviceInfo deviceInfo = new CudaDeviceInfo(cudaDevice))
  1077. {
  1078. if (deviceInfo.CudaComputeCapability < new Version(7, 5))
  1079. return;
  1080. }
  1081. GpuMat[] images = OpticalFlowImage();
  1082. GpuMat flow = new GpuMat();
  1083. GpuMat floatFlow = new GpuMat();
  1084. Stopwatch watch = Stopwatch.StartNew();
  1085. NvidiaOpticalFlow_2_0 nof = new NvidiaOpticalFlow_2_0(images[0].Size);
  1086. nof.Calc(images[0], images[1], flow);
  1087. nof.ConvertToFloat(flow, floatFlow);
  1088. watch.Stop();
  1089. EmguAssert.WriteLine(String.Format(
  1090. "Time: {0} milliseconds",
  1091. watch.ElapsedMilliseconds));
  1092. for (int i = 0; i < images.Length; i++)
  1093. {
  1094. images[i].Dispose();
  1095. }
  1096. }
  1097. }
  1098. }