{"id":2347,"date":"2012-08-20T18:43:49","date_gmt":"2012-08-21T01:43:49","guid":{"rendered":"http:\/\/mcclanahoochie.com\/blog\/?post_type=portfolio&#038;p=2347"},"modified":"2023-06-10T10:32:42","modified_gmt":"2023-06-10T17:32:42","slug":"local-contrast-enhancement-with-arrayfire-opencv","status":"publish","type":"post","link":"https:\/\/mcclanahoochie.com\/blog\/2012\/08\/local-contrast-enhancement-with-arrayfire-opencv\/","title":{"rendered":"Local Contrast Enhancement with ArrayFire + OpenCV"},"content":{"rendered":"<p>About one year ago, I wrote about a simple example of <a title=\"Image processing with LibJacket + OpenCV\" href=\"http:\/\/mcclanahoochie.com\/blog\/2011\/08\/image-processing-with-libjacket-opencv\/\">Image Processing with LibJacket + OpenCV<\/a>&#8230; and the trend continues today. In this post, I demonstrate how <strong><a href=\"http:\/\/www.accelereyes.com\/arrayfire\/c\/\" target=\"_blank\" rel=\"noopener\">ArrayFire<\/a><\/strong> (an improved version of LibJacket) can easily interop with OpenCV, through a simple example of <em><strong>unsharp maksing<\/strong> (<a href=\"http:\/\/www.cambridgeincolour.com\/tutorials\/local-contrast-enhancement.htm\" target=\"_blank\" rel=\"noopener\">local contrast enhancement<\/a>).<\/em><\/p>\n<h3><strong><em>\u00a0<\/em><\/strong><\/h3>\n<figure id=\"attachment_2350\" aria-describedby=\"caption-attachment-2350\" style=\"width: 574px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/mcclanahoochie.com\/blog\/portfolio\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2012-08-20-at-9-19-21-am_2\/\" target=\"_blank\" rel=\"noopener\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"2350\" data-permalink=\"https:\/\/mcclanahoochie.com\/blog\/2012\/08\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2012-08-20-at-9-19-21-am_2\/#main\" data-orig-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-9.19.21-AM_2.png?fit=1260%2C788&amp;ssl=1\" data-orig-size=\"1260,788\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"Screen Shot 2012-08-20 at 9.19.21 AM_2\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-9.19.21-AM_2.png?fit=1024%2C640&amp;ssl=1\" class=\"wp-image-2350\" title=\"Screen Shot 2012-08-20 at 9.19.21 AM_2\" src=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-9.19.21-AM_2-1024x640.png?resize=584%2C365\" alt=\"\" width=\"584\" height=\"365\" srcset=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-9.19.21-AM_2.png?resize=1024%2C640&amp;ssl=1 1024w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-9.19.21-AM_2.png?resize=300%2C187&amp;ssl=1 300w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-9.19.21-AM_2.png?resize=479%2C300&amp;ssl=1 479w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-9.19.21-AM_2.png?w=1260&amp;ssl=1 1260w\" sizes=\"(max-width: 584px) 100vw, 584px\" \/><\/a><figcaption id=\"caption-attachment-2350\" class=\"wp-caption-text\">Top Left: original webcam image | Top Right: histogram of V channel of input webcam image | \u00a0Bottom Left: image after LCE applied | Bottom Right: histogram of V channel of LCE image<\/figcaption><\/figure>\n<p><strong><em>Program Flow:<\/em><\/strong><\/p>\n<ol>\n<li>Capture steaming webcam video via OpenCV<\/li>\n<li>Convert current frame OpenCV Mat to an<em> ArrayFire <a href=\"http:\/\/www.accelereyes.com\/arrayfire\/c\/modules.htm\" target=\"_blank\" rel=\"noopener\">array<\/a><\/em><\/li>\n<li>Change colorspace from RGB to <em>HSV<\/em><\/li>\n<li>Apply <a href=\"http:\/\/en.wikipedia.org\/wiki\/Unsharp_masking\" target=\"_blank\" rel=\"noopener\">unsharp masking<\/a> (LCE) to the V-channel (based on slider-bar value)<\/li>\n<li>Convert back to RGB<\/li>\n<li>Compute <em>before<\/em> and <em>after<\/em> V-channel histograms<\/li>\n<li>Display images and plot V-channel histograms<\/li>\n<li>Use OpenCV&#8217;s trackbar to <em>interactively<\/em> adjust strength of LCE live<\/li>\n<\/ol>\n<div><\/div>\n<figure id=\"attachment_2355\" aria-describedby=\"caption-attachment-2355\" style=\"width: 594px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/mcclanahoochie.com\/blog\/portfolio\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2012-08-20-at-11-53-49-am_2\/\" target=\"_blank\" rel=\"noopener\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"2355\" data-permalink=\"https:\/\/mcclanahoochie.com\/blog\/2012\/08\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2012-08-20-at-11-53-49-am_2\/#main\" data-orig-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.49-AM_2.png?fit=1176%2C735&amp;ssl=1\" data-orig-size=\"1176,735\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"Screen Shot 2012-08-20 at 11.53.49 AM_2\" data-image-description=\"\" data-image-caption=\"&lt;p&gt;LCE adjustment value of 1.0&lt;\/p&gt;\n\" data-large-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.49-AM_2.png?fit=1024%2C640&amp;ssl=1\" class=\"wp-image-2355 size-large\" title=\"Screen Shot 2012-08-20 at 11.53.49 AM_2\" src=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.49-AM_2-1024x640.png?resize=604%2C378\" alt=\"\" width=\"604\" height=\"378\" srcset=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.49-AM_2.png?resize=1024%2C640&amp;ssl=1 1024w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.49-AM_2.png?resize=300%2C187&amp;ssl=1 300w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.49-AM_2.png?resize=480%2C300&amp;ssl=1 480w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.49-AM_2.png?w=1176&amp;ssl=1 1176w\" sizes=\"(max-width: 604px) 100vw, 604px\" \/><\/a><figcaption id=\"caption-attachment-2355\" class=\"wp-caption-text\">LCE adjustment value of 1.0<\/figcaption><\/figure>\n<figure id=\"attachment_2354\" aria-describedby=\"caption-attachment-2354\" style=\"width: 594px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/mcclanahoochie.com\/blog\/portfolio\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2012-08-20-at-11-53-57-am_2\/\" target=\"_blank\" rel=\"noopener\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"2354\" data-permalink=\"https:\/\/mcclanahoochie.com\/blog\/2012\/08\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2012-08-20-at-11-53-57-am_2\/#main\" data-orig-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.57-AM_2.png?fit=1176%2C735&amp;ssl=1\" data-orig-size=\"1176,735\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"Screen Shot 2012-08-20 at 11.53.57 AM_2\" data-image-description=\"\" data-image-caption=\"&lt;p&gt;LCE adjustment value of 5.0&lt;\/p&gt;\n\" data-large-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.57-AM_2.png?fit=1024%2C640&amp;ssl=1\" class=\"wp-image-2354 size-large\" title=\"Screen Shot 2012-08-20 at 11.53.57 AM_2\" src=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.57-AM_2-1024x640.png?resize=604%2C378\" alt=\"\" width=\"604\" height=\"378\" srcset=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.57-AM_2.png?resize=1024%2C640&amp;ssl=1 1024w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.57-AM_2.png?resize=300%2C187&amp;ssl=1 300w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.57-AM_2.png?resize=480%2C300&amp;ssl=1 480w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-11.53.57-AM_2.png?w=1176&amp;ssl=1 1176w\" sizes=\"(max-width: 604px) 100vw, 604px\" \/><\/a><figcaption id=\"caption-attachment-2354\" class=\"wp-caption-text\">LCE adjustment value of 5.0<\/figcaption><\/figure>\n<p>The 2 screenshots above show unsharp mask adjustment values of <em>1.0<\/em> and <em>5.0<\/em> (amount of difference layer to multiply back into original). It is interesting to see how<em> the histogram gets\u00a0progressively\u00a0smoother<\/em> as the &#8220;enhancement&#8221; factor increases.<\/p>\n<p>&nbsp;<\/p>\n<h3><strong><em>OpenCV Mat to Arrayfire ArraY Conversion<\/em><\/strong><\/h3>\n<p>OpenCV uses a <em>row-major, packed BGR<\/em> memory layout, where as ArrayFire uses a <em>column-major, channel based<\/em> (RGB are separate planes) memory layout. The conversion between the two is pretty simple; here is a snippit from the code running in the demo above:<\/p>\n<p><a href=\"http:\/\/mcclanahoochie.com\/blog\/portfolio\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2012-08-20-at-7-38-58-pm\/\" target=\"_blank\" rel=\"noopener\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"2361\" data-permalink=\"https:\/\/mcclanahoochie.com\/blog\/2012\/08\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2012-08-20-at-7-38-58-pm\/#main\" data-orig-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-7.38.58-PM.png?fit=606%2C439&amp;ssl=1\" data-orig-size=\"606,439\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"Screen Shot 2012-08-20 at 7.38.58 PM\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-7.38.58-PM.png?fit=606%2C439&amp;ssl=1\" class=\"aligncenter wp-image-2361 size-full\" title=\"Screen Shot 2012-08-20 at 7.38.58 PM\" src=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-7.38.58-PM.png?resize=606%2C439\" alt=\"\" width=\"606\" height=\"439\" srcset=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-7.38.58-PM.png?w=606&amp;ssl=1 606w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-7.38.58-PM.png?resize=300%2C217&amp;ssl=1 300w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-20-at-7.38.58-PM.png?resize=414%2C300&amp;ssl=1 414w\" sizes=\"(max-width: 606px) 100vw, 606px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h3><em><strong>Try it out for yourself!<\/strong><\/em><\/h3>\n<ul>\n<li>Download the\u00a0<a title=\"webcam_demo.cpp\" href=\"http:\/\/code.google.com\/p\/mcclanahoochie\/source\/browse\/cuda\/cam-arrayfire\/webcam_demo.cpp\" target=\"_blank\" rel=\"noopener\">webcam_demo.cpp<\/a>\u00a0source, the\u00a0<a href=\"http:\/\/code.google.com\/p\/mcclanahoochie\/source\/browse\/cuda\/cam-arrayfire\/Makefile\" target=\"_blank\" rel=\"noopener\">Makefile<\/a>\u00a0and the <a href=\"http:\/\/code.google.com\/p\/mcclanahoochie\/source\/browse\/cuda\/cam-arrayfire\/README\" target=\"_blank\" rel=\"noopener\">README<\/a><\/li>\n<li>Install\u00a0<a title=\"ArrayFire\" href=\"http:\/\/www.accelereyes.com\/products\/arrayfire\" target=\"_blank\" rel=\"noopener\">ArrayFire<\/a>\u00a0and\u00a0<a title=\"OpenCV\" href=\"http:\/\/opencv.org\" target=\"_blank\" rel=\"noopener\">OpenCV<\/a><\/li>\n<li>Or just\u00a0<a href=\"http:\/\/code.google.com\/p\/mcclanahoochie\/source\/browse\/cuda\/cam-arrayfire\/\">browse the source<\/a>\u00a0online<\/li>\n<\/ul>\n<p>Tested on a MacBook Pro using Mac OSX Lion, with\u00a0ArrayFire 1.1, OpenCV 2.4.1,\u00a0gcc 4.2.1, and\u00a0should work on Linux too, but unsure about Windows.<\/p>\n<p>Enjoy!<\/p>\n<hr \/>\n<p><em>Update<\/em>:<br \/>\nSame app using the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Mean-shift\" target=\"_blank\" rel=\"noopener\">meanshift<\/a> function available in the ArrayFire <a href=\"http:\/\/www.accelereyes.com\/nightly\/\" target=\"_blank\" rel=\"noopener\">nightly builds<\/a>; makes \u00a0everything cartoon-like \ud83d\ude42<\/p>\n<p><a href=\"http:\/\/mcclanahoochie.com\/blog\/portfolio\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2012-08-29-at-5-23-38-pm\/\" target=\"_blank\" rel=\"noopener\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"2382\" data-permalink=\"https:\/\/mcclanahoochie.com\/blog\/2012\/08\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2012-08-29-at-5-23-38-pm\/#main\" data-orig-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-29-at-5.23.38-PM.png?fit=1071%2C400&amp;ssl=1\" data-orig-size=\"1071,400\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"Screen Shot 2012-08-29 at 5.23.38 PM\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-29-at-5.23.38-PM.png?fit=1024%2C382&amp;ssl=1\" class=\"aligncenter wp-image-2382 size-large\" title=\"Screen Shot 2012-08-29 at 5.23.38 PM\" src=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-29-at-5.23.38-PM-1024x382.png?resize=604%2C225\" alt=\"\" width=\"604\" height=\"225\" srcset=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-29-at-5.23.38-PM.png?resize=1024%2C382&amp;ssl=1 1024w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-29-at-5.23.38-PM.png?resize=300%2C112&amp;ssl=1 300w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-29-at-5.23.38-PM.png?resize=500%2C186&amp;ssl=1 500w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2012-08-29-at-5.23.38-PM.png?w=1071&amp;ssl=1 1071w\" sizes=\"(max-width: 604px) 100vw, 604px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<p><em>Update<\/em><\/p>\n<p>Thanks to a request in the comments, I&#8217;ve updated<em><a href=\"https:\/\/code.google.com\/p\/mcclanahoochie\/source\/browse\/cuda\/cam-arrayfire\/af_helpers.cpp\" target=\"_blank\" rel=\"noopener\"><strong> [here]<\/strong> <\/a>a faster way to convert cv::Mat to af::array<\/em> , as well as handling all channel types, and even converting arrays back to Mats!\u00a0Below are what is new:<\/p>\n<p><a href=\"http:\/\/mcclanahoochie.com\/blog\/portfolio\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2013-03-01-at-5-18-59-pm\/\" target=\"_blank\" rel=\"noopener\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"2734\" data-permalink=\"https:\/\/mcclanahoochie.com\/blog\/2012\/08\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2013-03-01-at-5-18-59-pm\/#main\" data-orig-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.18.59-PM.png?fit=583%2C473&amp;ssl=1\" data-orig-size=\"583,473\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"Screen Shot 2013-03-01 at 5.18.59 PM\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.18.59-PM.png?fit=583%2C473&amp;ssl=1\" class=\"aligncenter wp-image-2734 size-full\" src=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.18.59-PM.png?resize=583%2C473\" alt=\"Screen Shot 2013-03-01 at 5.18.59 PM\" width=\"583\" height=\"473\" srcset=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.18.59-PM.png?w=583&amp;ssl=1 583w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.18.59-PM.png?resize=300%2C243&amp;ssl=1 300w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.18.59-PM.png?resize=369%2C300&amp;ssl=1 369w\" sizes=\"(max-width: 583px) 100vw, 583px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"http:\/\/mcclanahoochie.com\/blog\/portfolio\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2013-03-01-at-5-23-08-pm\/\" target=\"_blank\" rel=\"noopener\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"2735\" data-permalink=\"https:\/\/mcclanahoochie.com\/blog\/2012\/08\/local-contrast-enhancement-with-arrayfire-opencv\/screen-shot-2013-03-01-at-5-23-08-pm\/#main\" data-orig-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.23.08-PM.png?fit=546%2C347&amp;ssl=1\" data-orig-size=\"546,347\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"Screen Shot 2013-03-01 at 5.23.08 PM\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.23.08-PM.png?fit=546%2C347&amp;ssl=1\" class=\"aligncenter wp-image-2735 size-full\" src=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.23.08-PM.png?resize=546%2C347\" alt=\"Screen Shot 2013-03-01 at 5.23.08 PM\" width=\"546\" height=\"347\" srcset=\"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.23.08-PM.png?w=546&amp;ssl=1 546w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.23.08-PM.png?resize=300%2C190&amp;ssl=1 300w, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2012\/08\/Screen-Shot-2013-03-01-at-5.23.08-PM.png?resize=472%2C300&amp;ssl=1 472w\" sizes=\"(max-width: 546px) 100vw, 546px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Again, these new functions\u00a0[now in <a href=\"https:\/\/code.google.com\/p\/mcclanahoochie\/source\/browse\/cuda\/cam-arrayfire\/af_helpers.cpp\" target=\"_blank\" rel=\"noopener\">af_helers.cpp<\/a>\u00a0\/\u00a0<a href=\"https:\/\/code.google.com\/p\/mcclanahoochie\/source\/browse\/cuda\/cam-arrayfire\/af_helpers.h\" target=\"_blank\" rel=\"noopener\">af_helpers.h<\/a>] have not yet been integrated into this example program, but are added for example and can be used standalone.<\/p>\n<p><strong><a href=\"https:\/\/github.com\/arrayfire-community\/arrayfire_opencv\" target=\"_blank\" rel=\"noopener\">Now on github!<\/a><\/strong><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>About one year ago, I wrote about a simple example of Image Processing with LibJacket + OpenCV&#8230; and the trend continues today. In this post, I demonstrate how ArrayFire (an improved version of LibJacket) can easily interop with OpenCV, through a simple example of unsharp maksing (local contrast enhancement). \u00a0 Program Flow: Capture steaming webcam &#8230; <a title=\"Local Contrast Enhancement with ArrayFire + OpenCV\" class=\"read-more\" href=\"https:\/\/mcclanahoochie.com\/blog\/2012\/08\/local-contrast-enhancement-with-arrayfire-opencv\/\" aria-label=\"Read more about Local Contrast Enhancement with ArrayFire + OpenCV\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[1],"tags":[91,110,94,50,54,57,93,92,101,29],"class_list":["post-2347","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-arrayfire","tag-cuda","tag-enhancement","tag-image-editing","tag-image-processing","tag-imaging","tag-lce","tag-opencv","tag-programming","tag-projects"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pZdXI-BR","jetpack-related-posts":[{"id":1731,"url":"https:\/\/mcclanahoochie.com\/blog\/2011\/08\/image-processing-with-libjacket-opencv\/","url_meta":{"origin":2347,"position":0},"title":"Image processing with LibJacket + OpenCV","author":"mcclanahoochie","date":"August 24, 2011","format":false,"excerpt":"Update: one year later:\u00a0ArrayFire+OpenCV The OpenCV library is the de-facto standard for doing computer vision and image processing research projects. OpenCV includes several hundreds of computer vision algorithms, aimed for use in real-time vision applications. LibJacket is a matrix library built on CUDA. LibJacket offers hundreds of general matrix and\u2026","rel":"","context":"In \"arrayfire\"","block_context":{"text":"arrayfire","link":"https:\/\/mcclanahoochie.com\/blog\/tag\/arrayfire\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2011\/08\/Screen-shot-2011-08-24-at-2.42.52-PM-1024x640.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2011\/08\/Screen-shot-2011-08-24-at-2.42.52-PM-1024x640.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2011\/08\/Screen-shot-2011-08-24-at-2.42.52-PM-1024x640.png?resize=525%2C300 1.5x"},"classes":[]},{"id":1810,"url":"https:\/\/mcclanahoochie.com\/blog\/2011\/09\/opencv-vs-libjacket-gpu-sobel-filtering\/","url_meta":{"origin":2347,"position":1},"title":"OpenCV vs. LibJacket: GPU Sobel Filtering","author":"mcclanahoochie","date":"September 24, 2011","format":false,"excerpt":"Update: LibJacket has been renamed to\u00a0\u00a0ArrayFire. In response to a comment on a previous post about integrating LibJacket into an OpenCV project, below is just a simple FYI performance comparison of OpenCV's GPU Sobel filter versus LibJacket's conv2\u00a0convolution\u00a0filter (with a sobel kernel)... This is an evolutionary post, so be sure\u2026","rel":"","context":"In \"arrayfire\"","block_context":{"text":"arrayfire","link":"https:\/\/mcclanahoochie.com\/blog\/tag\/arrayfire\/"},"img":{"alt_text":"Sobel filter: OpenCV GPU vs. LibJacket","src":"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2011\/09\/cv-versus-jkt.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1896,"url":"https:\/\/mcclanahoochie.com\/blog\/2011\/11\/gpu-tv-l1-optical-flow-with-libjacket\/","url_meta":{"origin":2347,"position":2},"title":"GPU TV-L1 Optical Flow with ArrayFire","author":"mcclanahoochie","date":"November 6, 2011","format":false,"excerpt":"Update 1: LibJacket has been renamed to\u00a0\u00a0ArrayFire. Update 2: Huang Chao-Hui was nice enough to port the LibJacket code mentioned here to ArrayFire - see his work here. As one of my\u00a0Computer Vision\u00a0class\u00a0projects, I decided to implement optical flow, because I wanted to learn more about optical flow, and also\u2026","rel":"","context":"In \"arrayfire\"","block_context":{"text":"arrayfire","link":"https:\/\/mcclanahoochie.com\/blog\/tag\/arrayfire\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2011\/11\/jkt-oflow-tvl1-1024x626.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2011\/11\/jkt-oflow-tvl1-1024x626.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2011\/11\/jkt-oflow-tvl1-1024x626.png?resize=525%2C300 1.5x"},"classes":[]},{"id":1876,"url":"https:\/\/mcclanahoochie.com\/blog\/2011\/10\/gpu-convolution-opencv-gpu-and-libjacket-part-2\/","url_meta":{"origin":2347,"position":3},"title":"GPU Convolutions: OpenCV GPU and LibJacket &#8211; Part 2","author":"mcclanahoochie","date":"October 24, 2011","format":false,"excerpt":"This is a response to my earlier post comparing OpenCV's gpu::convolve() and LibJacket's jkt::conv2() convolution functions, at various image and kernel sizes. That post generated a lot of traffic, most notably from the OpenCV developer community. Taking note of this, it seems that the folks at Willow Garage have re-vamped\u2026","rel":"","context":"In \"arrayfire\"","block_context":{"text":"arrayfire","link":"https:\/\/mcclanahoochie.com\/blog\/tag\/arrayfire\/"},"img":{"alt_text":".","src":"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2011\/10\/Screenshot-f2-2075.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2011\/10\/Screenshot-f2-2075.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2011\/10\/Screenshot-f2-2075.png?resize=525%2C300 1.5x"},"classes":[]},{"id":2503,"url":"https:\/\/mcclanahoochie.com\/blog\/2012\/11\/sc12-arrayfire-webcam-demo\/","url_meta":{"origin":2347,"position":4},"title":"SC12 ArrayFire Demos","author":"mcclanahoochie","date":"November 25, 2012","format":false,"excerpt":"I got the\u00a0privilege\u00a0of developing some of the\u00a0Super Computing 2012\u00a0(SC12)\u00a0booth demos\u00a0for\u00a0AccelerEyes,\u00a0to showcase\u00a0ArrayFire. Above is an\u00a0ArrayFire\u00a0demo running at SC12 on an nVidia GPU. This demo (source code HERE) uses OpenCV to capture webcam video and processes the stream in several different ways, in real-time.\u00a0From top-left to bottom-right: Sobel filter, ArrayFire logo, Motion\u2026","rel":"","context":"In \"arrayfire\"","block_context":{"text":"arrayfire","link":"https:\/\/mcclanahoochie.com\/blog\/tag\/arrayfire\/"},"img":{"alt_text":"Sobel filter, ArrayFire logo, Motion (frame differencing), Source image, Histogram plot, Mean-shift filter","src":"https:\/\/i0.wp.com\/lh5.googleusercontent.com\/-5haNiIGwpIk\/UKw-ct6OHDI\/AAAAAAAAMd8\/lxnzbUk44Kc\/s912\/20121114_111339.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":1153,"url":"https:\/\/mcclanahoochie.com\/blog\/2011\/04\/computer-vision-on-android-opencv\/","url_meta":{"origin":2347,"position":5},"title":"Computer Vision on Android with OpenCV","author":"mcclanahoochie","date":"April 8, 2011","format":false,"excerpt":"March 2011 With the help of Motodev Studio for Android, I've\u00a0extracted\u00a0the\u00a0android-opencv JNI\u00a0camera example and spawned a fork of my original computer vision app,\u00a0Viewer, to an OpenCV version: ViewerCV. Both are\u00a0available on Git Hub\u00a0as open source software example of doing Computer Vision on Android with OpenCV. Viewer Features: *FAST Features (default\u2026","rel":"","context":"In \"android\"","block_context":{"text":"android","link":"https:\/\/mcclanahoochie.com\/blog\/tag\/android\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/mcclanahoochie.com\/blog\/wp-content\/uploads\/2011\/04\/viewercv1.png?resize=350%2C200","width":350,"height":200},"classes":[]}],"jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/mcclanahoochie.com\/blog\/wp-json\/wp\/v2\/posts\/2347","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mcclanahoochie.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mcclanahoochie.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mcclanahoochie.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mcclanahoochie.com\/blog\/wp-json\/wp\/v2\/comments?post=2347"}],"version-history":[{"count":0,"href":"https:\/\/mcclanahoochie.com\/blog\/wp-json\/wp\/v2\/posts\/2347\/revisions"}],"wp:attachment":[{"href":"https:\/\/mcclanahoochie.com\/blog\/wp-json\/wp\/v2\/media?parent=2347"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mcclanahoochie.com\/blog\/wp-json\/wp\/v2\/categories?post=2347"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mcclanahoochie.com\/blog\/wp-json\/wp\/v2\/tags?post=2347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}