{"id":1677,"date":"2015-05-17T22:06:58","date_gmt":"2015-05-17T21:06:58","guid":{"rendered":"http:\/\/www.2diabolos.com\/blog\/?page_id=1677"},"modified":"2024-08-26T19:46:29","modified_gmt":"2024-08-26T18:46:29","slug":"optimize-your-opencv-code-with-numpy","status":"publish","type":"page","link":"https:\/\/www.2diabolos.com\/blog\/python-and-spyder\/optimize-your-opencv-code-with-numpy\/","title":{"rendered":"Optimize your OpenCV code with Numpy"},"content":{"rendered":"<div class=\"columns\"><p>Sometimes, you may optimize good code with other good one. Numpy is usually the best, so if you think that you may do a trick other do, but with numpy, you should give a try.<\/p>\n<p>I did it for the convertion \u00ab\u00a0COLOR_BGR2RGB\u00a0\u00bb from OpenCV (a very good open-source project, by the way) which convert a \u00ab\u00a0Blue-Green-Red\u00a0\u00bb encoded image into a RGB format. You already guessed, it just swap the blue channel with the red one. As a clever project, they use numpy as a library for their array. But they seem not to use it internally, just for the Python binding. And that&rsquo;s a pity.<\/p>\n<p>So the following script creates a random \u00ab\u00a0image\u00a0\u00bb (the biggest possible on my system: if I take twice bigger, I got memory error) and swap the Blue and Red channels with cvtColor from OpenCV library, or with numpy indexing.<\/p>\n<p>Thing worth to notice :<\/p>\n<ol>\n<li>the use of \u00ab\u00a0time.clock()\u00a0\u00bb which is much better than \u00ab\u00a0time.time()\u00a0\u00bb (milisecond precision)<\/li>\n<li>the nice Numpy notation to reverse the 3 first index in a dimension. (I could have written r=r[:,:,::-1], but I needed to extract from a bigger array (with 4 channels) and I kept the syntax)<\/li>\n<li>I test each value of the matrix with just a line : \u00ab\u00a0np.any(a!=b)\u00a0\u00bb<\/li>\n<\/ol>\n<p>[pastacode lang=\u00a0\u00bbpython\u00a0\u00bb path_id=\u00a0\u00bb\/2015\/05\/cvtColor-VS-numpy.py\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb lines=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbfile\u00a0\u00bb\/]<\/p>\n<p>On my computer, I got :<\/p>\n<p>OpenCV clock : 1.65601427898<br \/>\nNumpy indexing clock : 0.000214317560064<\/p>\n<p>Yeah, that&rsquo;s an optimization factor bigger than 7500 (I even got 8500 factor for a 100 for loop) ! nearly 4 order of magnitude!<\/p>\n<p>OK, I admit that it&rsquo;s not that important on a 640&#215;480 webcam image, but you are constantly using such conversion when using openCV videocapture, so it might worth the declaration of a 2 line function!<\/p>\n<p>I even double checked with a function declaration, like this :<\/p>\n<pre>def numpySwap(rr):\r\n    r3=rr[:, :, 2::-1]\r\n    return r3\r\n<\/pre>\n<p>it should be slower because the rand matrix is being copied in memory. it is about the same. So please OpenCV guys, if you read this, could you optimize your code ?<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Sometimes, you may optimize good code with other good one. Numpy is usually the best, so if you think that you may do a trick other do, but with numpy, you should give a try. I did it for the convertion \u00ab\u00a0COLOR_BGR2RGB\u00a0\u00bb from OpenCV (a very good open-source project, by the way) which convert a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":861,"menu_order":100,"comment_status":"closed","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-1677","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.2diabolos.com\/blog\/wp-json\/wp\/v2\/pages\/1677","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.2diabolos.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.2diabolos.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.2diabolos.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.2diabolos.com\/blog\/wp-json\/wp\/v2\/comments?post=1677"}],"version-history":[{"count":9,"href":"https:\/\/www.2diabolos.com\/blog\/wp-json\/wp\/v2\/pages\/1677\/revisions"}],"predecessor-version":[{"id":1804,"href":"https:\/\/www.2diabolos.com\/blog\/wp-json\/wp\/v2\/pages\/1677\/revisions\/1804"}],"up":[{"embeddable":true,"href":"https:\/\/www.2diabolos.com\/blog\/wp-json\/wp\/v2\/pages\/861"}],"wp:attachment":[{"href":"https:\/\/www.2diabolos.com\/blog\/wp-json\/wp\/v2\/media?parent=1677"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}