Cv2_highgui.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. using OpenCvSharp.Internal;
  2. using OpenCvSharp.Internal.Vectors;
  3. // ReSharper disable UnusedMember.Global
  4. namespace OpenCvSharp;
  5. static partial class Cv2
  6. {
  7. /// <summary>
  8. /// Creates a window.
  9. /// </summary>
  10. /// <param name="winName">Name of the window in the window caption that may be used as a window identifier.</param>
  11. /// <param name="flags">
  12. /// Flags of the window. Currently the only supported flag is CV WINDOW AUTOSIZE. If this is set,
  13. /// the window size is automatically adjusted to fit the displayed image (see imshow ), and the user can not change the window size manually.
  14. /// </param>
  15. public static void NamedWindow(string winName, WindowFlags flags = WindowFlags.Normal)
  16. {
  17. if (string.IsNullOrEmpty(winName))
  18. throw new ArgumentException("null or empty string.", nameof(winName));
  19. NativeMethods.HandleException(
  20. NativeMethods.highgui_namedWindow(winName, (int) flags));
  21. }
  22. /// <summary>
  23. /// Destroys the specified window.
  24. /// </summary>
  25. /// <param name="winName"></param>
  26. public static void DestroyWindow(string winName)
  27. {
  28. if (string.IsNullOrEmpty(winName))
  29. throw new ArgumentException("null or empty string.", nameof(winName));
  30. NativeMethods.HandleException(
  31. NativeMethods.highgui_destroyWindow(winName));
  32. }
  33. /// <summary>
  34. /// Destroys all of the HighGUI windows.
  35. /// </summary>
  36. public static void DestroyAllWindows()
  37. {
  38. NativeMethods.HandleException(
  39. NativeMethods.highgui_destroyAllWindows());
  40. }
  41. /// <summary>
  42. ///
  43. /// </summary>
  44. /// <returns></returns>
  45. public static int StartWindowThread()
  46. {
  47. NativeMethods.HandleException(
  48. NativeMethods.highgui_startWindowThread(out var ret));
  49. return ret;
  50. }
  51. /// <summary>
  52. /// Waits for a pressed key.
  53. /// Similar to #waitKey, but returns full key code.
  54. /// Key code is implementation specific and depends on used backend: QT/GTK/Win32/etc
  55. /// </summary>
  56. /// <param name="delay">Delay in milliseconds. 0 is the special value that means ”forever”</param>
  57. /// <returns>Returns the code of the pressed key or -1 if no key was pressed before the specified time had elapsed.</returns>
  58. public static int WaitKeyEx(int delay = 0)
  59. {
  60. NativeMethods.HandleException(
  61. NativeMethods.highgui_waitKeyEx(delay, out var ret));
  62. return ret;
  63. }
  64. /// <summary>
  65. /// Waits for a pressed key.
  66. /// </summary>
  67. /// <param name="delay">Delay in milliseconds. 0 is the special value that means ”forever”</param>
  68. /// <returns>Returns the code of the pressed key or -1 if no key was pressed before the specified time had elapsed.</returns>
  69. public static int WaitKey(int delay = 0)
  70. {
  71. NativeMethods.HandleException(
  72. NativeMethods.highgui_waitKey(delay, out var ret));
  73. return ret;
  74. }
  75. /// <summary>
  76. /// Displays the image in the specified window
  77. /// </summary>
  78. /// <param name="winName">Name of the window.</param>
  79. /// <param name="mat">Image to be shown.</param>
  80. public static void ImShow(string winName, Mat mat)
  81. {
  82. if (string.IsNullOrEmpty(winName))
  83. throw new ArgumentException("null or empty string.", nameof(winName));
  84. if (mat is null)
  85. throw new ArgumentNullException(nameof(mat));
  86. NativeMethods.HandleException(
  87. NativeMethods.highgui_imshow(winName, mat.CvPtr));
  88. GC.KeepAlive(mat);
  89. }
  90. /// <summary>
  91. /// Resizes window to the specified size
  92. /// </summary>
  93. /// <param name="winName">Window name</param>
  94. /// <param name="width">The new window width</param>
  95. /// <param name="height">The new window height</param>
  96. public static void ResizeWindow(string winName, int width, int height)
  97. {
  98. if (string.IsNullOrEmpty(winName))
  99. throw new ArgumentException("null or empty string.", nameof(winName));
  100. NativeMethods.HandleException(
  101. NativeMethods.highgui_resizeWindow(winName, width, height));
  102. }
  103. /// <summary>
  104. /// Resizes window to the specified size
  105. /// </summary>
  106. /// <param name="winName">Window name</param>
  107. /// <param name="size">The new window size</param>
  108. public static void ResizeWindow(string winName, Size size)
  109. {
  110. ResizeWindow(winName, size.Width, size.Height);
  111. }
  112. /// <summary>
  113. /// Moves window to the specified position
  114. /// </summary>
  115. /// <param name="winName">Window name</param>
  116. /// <param name="x">The new x-coordinate of the window</param>
  117. /// <param name="y">The new y-coordinate of the window</param>
  118. public static void MoveWindow(string winName, int x, int y)
  119. {
  120. if (string.IsNullOrEmpty(winName))
  121. throw new ArgumentException("null or empty string.", nameof(winName));
  122. NativeMethods.HandleException(
  123. NativeMethods.highgui_moveWindow(winName, x, y));
  124. }
  125. /// <summary>
  126. /// Changes parameters of a window dynamically.
  127. /// </summary>
  128. /// <param name="winName">Name of the window.</param>
  129. /// <param name="propId">Window property to retrieve.</param>
  130. /// <param name="propValue">New value of the window property.</param>
  131. public static void SetWindowProperty(string winName, WindowPropertyFlags propId, double propValue)
  132. {
  133. if (string.IsNullOrEmpty(winName))
  134. throw new ArgumentException("null or empty string.", nameof(winName));
  135. NativeMethods.HandleException(
  136. NativeMethods.highgui_setWindowProperty(winName, (int) propId, propValue));
  137. }
  138. /// <summary>
  139. /// Updates window title
  140. /// </summary>
  141. /// <param name="winName">Name of the window</param>
  142. /// <param name="title">New title</param>
  143. public static void SetWindowTitle(string winName, string title)
  144. {
  145. if (string.IsNullOrEmpty(winName))
  146. throw new ArgumentException("null or empty string.", nameof(winName));
  147. if (string.IsNullOrEmpty(title))
  148. throw new ArgumentException("null or empty string.", nameof(title));
  149. NativeMethods.HandleException(
  150. NativeMethods.highgui_setWindowTitle(winName, title));
  151. }
  152. /// <summary>
  153. /// Provides parameters of a window.
  154. /// </summary>
  155. /// <param name="winName">Name of the window.</param>
  156. /// <param name="propId">Window property to retrieve.</param>
  157. /// <returns></returns>
  158. public static double GetWindowProperty(string winName, WindowPropertyFlags propId)
  159. {
  160. if (string.IsNullOrEmpty(winName))
  161. throw new ArgumentException("null or empty string.", nameof(winName));
  162. NativeMethods.HandleException(
  163. NativeMethods.highgui_getWindowProperty(winName, (int) propId, out var ret));
  164. return ret;
  165. }
  166. /// <summary>
  167. /// Provides rectangle of image in the window.
  168. /// The function getWindowImageRect returns the client screen coordinates, width and height of the image rendering area.
  169. /// </summary>
  170. /// <param name="winName">Name of the window.</param>
  171. /// <returns></returns>
  172. public static Rect GetWindowImageRect(string winName)
  173. {
  174. if (string.IsNullOrEmpty(winName))
  175. throw new ArgumentException("null or empty string.", nameof(winName));
  176. NativeMethods.HandleException(
  177. NativeMethods.highgui_getWindowImageRect(winName, out var ret));
  178. return ret;
  179. }
  180. /// <summary>
  181. /// Sets the callback function for mouse events occuring within the specified window.
  182. /// </summary>
  183. /// <param name="windowName">Name of the window. </param>
  184. /// <param name="onMouse">Reference to the function to be called every time mouse event occurs in the specified window. </param>
  185. /// <param name="userData"></param>
  186. public static void SetMouseCallback(string windowName, MouseCallback onMouse, IntPtr userData = default)
  187. {
  188. if (string.IsNullOrEmpty(windowName))
  189. throw new ArgumentNullException(nameof(windowName));
  190. if (onMouse is null)
  191. throw new ArgumentNullException(nameof(onMouse));
  192. NativeMethods.HandleException(
  193. NativeMethods.highgui_setMouseCallback(windowName, onMouse, userData));
  194. }
  195. /// <summary>
  196. /// Gets the mouse-wheel motion delta, when handling mouse-wheel events cv::EVENT_MOUSEWHEEL and cv::EVENT_MOUSEHWHEEL.
  197. ///
  198. /// For regular mice with a scroll-wheel, delta will be a multiple of 120. The value 120 corresponds to
  199. /// a one notch rotation of the wheel or the threshold for action to be taken and one such action should
  200. /// occur for each delta.Some high-precision mice with higher-resolution freely-rotating wheels may
  201. /// generate smaller values.
  202. ///
  203. /// For cv::EVENT_MOUSEWHEEL positive and negative values mean forward and backward scrolling,
  204. /// respectively.For cv::EVENT_MOUSEHWHEEL, where available, positive and negative values mean right and
  205. /// left scrolling, respectively.
  206. /// </summary>
  207. /// <param name="flags">The mouse callback flags parameter.</param>
  208. /// <returns></returns>
  209. public static int GetMouseWheelDelta(MouseEventFlags flags)
  210. {
  211. NativeMethods.HandleException(
  212. NativeMethods.highgui_getMouseWheelDelta((int)flags, out var ret));
  213. return ret;
  214. }
  215. /// <summary>
  216. /// Selects ROI on the given image.
  217. /// Function creates a window and allows user to select a ROI using mouse.
  218. /// Controls: use `space` or `enter` to finish selection, use key `c` to cancel selection (function will return the zero cv::Rect).
  219. /// </summary>
  220. /// <param name="windowName">name of the window where selection process will be shown.</param>
  221. /// <param name="img">image to select a ROI.</param>
  222. /// <param name="showCrosshair">if true crosshair of selection rectangle will be shown.</param>
  223. /// <param name="fromCenter">if true center of selection will match initial mouse position. In opposite case a corner of
  224. /// selection rectangle will correspond to the initial mouse position.</param>
  225. /// <returns>selected ROI or empty rect if selection canceled.</returns>
  226. // ReSharper disable once InconsistentNaming
  227. public static Rect SelectROI(string windowName, InputArray img, bool showCrosshair = true, bool fromCenter = false)
  228. {
  229. if (string.IsNullOrEmpty(windowName))
  230. throw new ArgumentNullException(nameof(windowName));
  231. if (img is null)
  232. throw new ArgumentNullException(nameof(img));
  233. img.ThrowIfDisposed();
  234. NativeMethods.HandleException(
  235. NativeMethods.highgui_selectROI1(windowName, img.CvPtr, showCrosshair ? 1 : 0, fromCenter ? 1 : 0, out var ret));
  236. GC.KeepAlive(img);
  237. return ret;
  238. }
  239. /// <summary>
  240. /// Selects ROI on the given image.
  241. /// Function creates a window and allows user to select a ROI using mouse.
  242. /// Controls: use `space` or `enter` to finish selection, use key `c` to cancel selection (function will return the zero cv::Rect).
  243. /// </summary>
  244. /// <param name="img">image to select a ROI.</param>
  245. /// <param name="showCrosshair">if true crosshair of selection rectangle will be shown.</param>
  246. /// <param name="fromCenter">if true center of selection will match initial mouse position. In opposite case a corner of
  247. /// selection rectangle will correspond to the initial mouse position.</param>
  248. /// <returns>selected ROI or empty rect if selection canceled.</returns>
  249. // ReSharper disable once InconsistentNaming
  250. public static Rect SelectROI(InputArray img, bool showCrosshair = true, bool fromCenter = false)
  251. {
  252. if (img is null)
  253. throw new ArgumentNullException(nameof(img));
  254. img.ThrowIfDisposed();
  255. NativeMethods.HandleException(
  256. NativeMethods.highgui_selectROI2(img.CvPtr, showCrosshair ? 1 : 0, fromCenter ? 1 : 0, out var ret));
  257. GC.KeepAlive(img);
  258. return ret;
  259. }
  260. /// <summary>
  261. /// Selects ROIs on the given image.
  262. /// Function creates a window and allows user to select a ROIs using mouse.
  263. /// Controls: use `space` or `enter` to finish current selection and start a new one,
  264. /// use `esc` to terminate multiple ROI selection process.
  265. /// </summary>
  266. /// <param name="windowName">name of the window where selection process will be shown.</param>
  267. /// <param name="img">image to select a ROI.</param>
  268. /// <param name="showCrosshair">if true crosshair of selection rectangle will be shown.</param>
  269. /// <param name="fromCenter">if true center of selection will match initial mouse position. In opposite case a corner of
  270. /// selection rectangle will correspond to the initial mouse position.</param>
  271. /// <returns>selected ROIs.</returns>
  272. // ReSharper disable once InconsistentNaming
  273. public static Rect[] SelectROIs(string windowName, InputArray img, bool showCrosshair = true, bool fromCenter = false)
  274. {
  275. if (string.IsNullOrEmpty(windowName))
  276. throw new ArgumentNullException(nameof(windowName));
  277. if (img is null)
  278. throw new ArgumentNullException(nameof(img));
  279. img.ThrowIfDisposed();
  280. using var boundingBoxesVec = new VectorOfRect();
  281. NativeMethods.HandleException(
  282. NativeMethods.highgui_selectROIs(windowName, img.CvPtr, boundingBoxesVec.CvPtr, showCrosshair ? 1 : 0, fromCenter ? 1 : 0));
  283. GC.KeepAlive(img);
  284. return boundingBoxesVec.ToArray();
  285. }
  286. /// <summary>
  287. /// Creates a trackbar and attaches it to the specified window.
  288. /// The function createTrackbar creates a trackbar(a slider or range control) with the specified name
  289. /// and range, assigns a variable value to be a position synchronized with the trackbar and specifies
  290. /// the callback function onChange to be called on the trackbar position change.The created trackbar is
  291. /// displayed in the specified window winName.
  292. /// </summary>
  293. /// <param name="trackbarName">Name of the created trackbar.</param>
  294. /// <param name="winName">Name of the window that will be used as a parent of the created trackbar.</param>
  295. /// <param name="value">Optional pointer to an integer variable whose value reflects the position of the slider.Upon creation,
  296. /// the slider position is defined by this variable.</param>
  297. /// <param name="count">Maximal position of the slider. The minimal position is always 0.</param>
  298. /// <param name="onChange">Pointer to the function to be called every time the slider changes position.
  299. /// This function should be prototyped as void Foo(int, void\*); , where the first parameter is the trackbar
  300. /// position and the second parameter is the user data(see the next parameter). If the callback is
  301. /// the NULL pointer, no callbacks are called, but only value is updated.</param>
  302. /// <param name="userData">User data that is passed as is to the callback. It can be used to handle trackbar events without using global variables.</param>
  303. /// <returns></returns>
  304. public static int CreateTrackbar(string trackbarName, string winName,
  305. ref int value, int count, TrackbarCallbackNative? onChange = null, IntPtr userData = default)
  306. {
  307. if (trackbarName is null)
  308. throw new ArgumentNullException(nameof(trackbarName));
  309. if (winName is null)
  310. throw new ArgumentNullException(nameof(winName));
  311. NativeMethods.HandleException(
  312. NativeMethods.highgui_createTrackbar(trackbarName, winName, ref value, count, onChange, userData, out var ret));
  313. return ret;
  314. }
  315. /// <summary>
  316. /// Creates a trackbar and attaches it to the specified window.
  317. /// The function createTrackbar creates a trackbar(a slider or range control) with the specified name
  318. /// and range, assigns a variable value to be a position synchronized with the trackbar and specifies
  319. /// the callback function onChange to be called on the trackbar position change.The created trackbar is
  320. /// displayed in the specified window winName.
  321. /// </summary>
  322. /// <param name="trackbarName">Name of the created trackbar.</param>
  323. /// <param name="winName">Name of the window that will be used as a parent of the created trackbar.</param>
  324. /// <param name="count">Maximal position of the slider. The minimal position is always 0.</param>
  325. /// <param name="onChange">Pointer to the function to be called every time the slider changes position.
  326. /// This function should be prototyped as void Foo(int, void\*); , where the first parameter is the trackbar
  327. /// position and the second parameter is the user data(see the next parameter). If the callback is
  328. /// the NULL pointer, no callbacks are called, but only value is updated.</param>
  329. /// <param name="userData">User data that is passed as is to the callback. It can be used to handle trackbar events without using global variables.</param>
  330. /// <returns></returns>
  331. public static int CreateTrackbar(string trackbarName, string winName,
  332. int count, TrackbarCallbackNative? onChange = null, IntPtr userData = default)
  333. {
  334. if (trackbarName is null)
  335. throw new ArgumentNullException(nameof(trackbarName));
  336. if (winName is null)
  337. throw new ArgumentNullException(nameof(winName));
  338. NativeMethods.HandleException(
  339. NativeMethods.highgui_createTrackbar(trackbarName, winName, IntPtr.Zero, count, onChange, userData, out var ret));
  340. return ret;
  341. }
  342. /// <summary>
  343. /// Returns the trackbar position.
  344. /// </summary>
  345. /// <param name="trackbarName">Name of the trackbar.</param>
  346. /// <param name="winName">Name of the window that is the parent of the trackbar.</param>
  347. /// <returns>trackbar position</returns>
  348. public static int GetTrackbarPos(string trackbarName, string winName)
  349. {
  350. if (trackbarName is null)
  351. throw new ArgumentNullException(nameof(trackbarName));
  352. NativeMethods.HandleException(
  353. NativeMethods.highgui_getTrackbarPos(trackbarName, winName, out var ret));
  354. return ret;
  355. }
  356. /// <summary>
  357. /// Sets the trackbar position.
  358. /// </summary>
  359. /// <param name="trackbarName">Name of the trackbar.</param>
  360. /// <param name="winName">Name of the window that is the parent of trackbar.</param>
  361. /// <param name="pos">New position.</param>
  362. public static void SetTrackbarPos(string trackbarName, string winName, int pos)
  363. {
  364. if (trackbarName is null)
  365. throw new ArgumentNullException(nameof(trackbarName));
  366. NativeMethods.HandleException(
  367. NativeMethods.highgui_setTrackbarPos(trackbarName, winName, pos));
  368. }
  369. /// <summary>
  370. /// Sets the trackbar maximum position.
  371. /// The function sets the maximum position of the specified trackbar in the specified window.
  372. /// </summary>
  373. /// <param name="trackbarName">Name of the trackbar.</param>
  374. /// <param name="winName">Name of the window that is the parent of trackbar.</param>
  375. /// <param name="maxVal">New maximum position.</param>
  376. public static void SetTrackbarMax(string trackbarName, string winName, int maxVal)
  377. {
  378. if (trackbarName is null)
  379. throw new ArgumentNullException(nameof(trackbarName));
  380. NativeMethods.HandleException(
  381. NativeMethods.highgui_setTrackbarMax(trackbarName, winName, maxVal));
  382. }
  383. /// <summary>
  384. /// Sets the trackbar minimum position.
  385. /// The function sets the minimum position of the specified trackbar in the specified window.
  386. /// </summary>
  387. /// <param name="trackbarName">Name of the trackbar.</param>
  388. /// <param name="winName">Name of the window that is the parent of trackbar.</param>
  389. /// <param name="minVal">New minimum position.</param>
  390. public static void SetTrackbarMin(string trackbarName, string winName, int minVal)
  391. {
  392. if (trackbarName is null)
  393. throw new ArgumentNullException(nameof(trackbarName));
  394. NativeMethods.HandleException(
  395. NativeMethods.highgui_setTrackbarMin(trackbarName, winName, minVal));
  396. }
  397. /// <summary>
  398. /// get native window handle (HWND in case of Win32 and Widget in case of X Window)
  399. /// </summary>
  400. /// <param name="windowName"></param>
  401. public static IntPtr GetWindowHandle(string windowName)
  402. {
  403. if (windowName is null)
  404. throw new ArgumentNullException(nameof(windowName));
  405. NativeMethods.HandleException(
  406. NativeMethods.highgui_cvGetWindowHandle(windowName, out var ret));
  407. return ret;
  408. }
  409. #if WINRT
  410. // MP! Added: To correctly support imShow under WinRT.
  411. /// <summary>
  412. /// Initialize XAML container panel for use by ImShow
  413. /// </summary>
  414. /// <param name="panel">Panel container.</param>
  415. public static void InitContainer(object panel)
  416. {
  417. NativeMethods.HandleException(
  418. NativeMethods.highgui_initContainer(panel));
  419. }
  420. #endif
  421. }