{"id":1694,"date":"2015-01-16T00:00:00","date_gmt":"2015-01-16T08:00:00","guid":{"rendered":"http:\/\/192.168.3.4\/?p=1694"},"modified":"2018-01-09T06:49:49","modified_gmt":"2018-01-09T14:49:49","slug":"rpi-image-processing","status":"publish","type":"post","link":"https:\/\/www.cloudacm.com\/?p=1694","title":{"rendered":"RPi image processing"},"content":{"rendered":"<p><strong>Introduction &#8211; processing images with ImageMagick<\/strong><\/p>\n<p>I first\u00a0posted about ImageMagick in early June, last year. \u00a0Then late\u00a0November, I covered the steps to install it and use it on RPi. \u00a0The features of ImageMagick are fairly extensive, I won&#8217;t go into all of them here. \u00a0As a guide, I recommend\u00a0Michael Still&#8217;s book titled &#8220;<a href=\"http:\/\/www.apress.com\/9781590595909\" target=\"_blank\">The Definitive Guide to ImageMagick<\/a>&#8221; through APress publishing. \u00a0For additional information, you may want to look at\u00a0Sohail Salehi&#8217;s book titled &#8220;<a href=\"https:\/\/www.packtpub.com\/hardware-and-creative\/imagemagick-tricks\" target=\"_blank\">ImageMagick Tricks<\/a>&#8221; from Packt Publishing.<\/p>\n<p><a href=\"http:\/\/www.imagemagick.org\/\" target=\"_blank\">ImageMagick<\/a>\u00a0is defined on its\u00a0website.<\/p>\n<p><em>&#8220;&#8230;is designed for batch processing of images. That is, it allow(s) you to combine image processing operations in a script (shell, DOS, Perl, PHP, etc.) so the operations can be applied to many images, or as a sub-system of some other tool, such as a Web application, video processing tool, panorama generator, etc. It is not a GUI image editor&#8230;&#8221;<\/em><\/p>\n<p>It seems that image processing is a perfect fit for ImageMagick on the RPi. \u00a0I&#8217;ve been web scraping images since last quarter. \u00a0These raw images are a perfect resource to process for data analysis. \u00a0Real time processing lends itself to other uses as well, one being augmented reality.<\/p>\n<p>In this post, I&#8217;ll cover the basics of ImageMagick. \u00a0We&#8217;ll see examples of image processing to create video streams. \u00a0I&#8217;ll also go over how to extract data from images to represent a condition, which we can plot over time. \u00a0We&#8217;ll also see how to reprocess image data into new images and video for an enhanced visual experience. \u00a0We have a lot cover, so lets start.<\/p>\n<p><strong>Purpose &#8211; Seeing the light<\/strong><\/p>\n<p>I&#8217;ve covered image processing before, but this will be the first time that we will actually manipulate and quantify data sets from images. \u00a0We will do this so the\u00a0images become an extensible\u00a0daylight, weather, or\u00a0traffic sensor. \u00a0The images contain visual data that is easy for humans to understand, but the details often get overlooked. \u00a0This where the RPi comes in. \u00a0It can processes the images into data sets. \u00a0This is useful because it gives us a better understanding of the image content. \u00a0Not only that, I gives us the ability to program the RPi to perform an\u00a0action based on a condition. \u00a0In essence, we will program our RPi to do something in response to what it sees.<\/p>\n<p><strong>Details &#8211; It is in there, you just need to look harder<\/strong><\/p>\n<p>First things first, I would like to revisit the process of converting images to a format that will allow video creation. \u00a0Since images gathered from cameras typically are in the JPG format, we won&#8217;t\u00a0have much trouble in converting the images to video. \u00a0However, images that contain\u00a0few color variations usually are in a GIF or PNG format. \u00a0I&#8217;ve run into issues with background transparencies. \u00a0So, here is the command to use when converting both GIF and PNG formats to JPG.<\/p>\n<pre>\r\n<code>\r\nconvert -background white -flatten  -compress none -quality 100100  SourceImage DestinationImage\r\n<\/code>\r\n<\/pre>\n<p>This can be a problem if you&#8217;re converting several files in a directory. \u00a0For that, I use this batch command\u00a0when converting images on my Windows machine.<\/p>\n<pre>\r\n<code>\r\n@echo off\r\n\r\ndir *.gif \/b &gt; FileList.txt\r\n\r\nFOR \/F \"tokens=*\" %%A IN (FileList.txt) DO (\r\nconvert -background white -flatten -compress none -quality 100100 %%A %%A.jpg\r\n)\r\n\r\nexit\r\n<\/code>\r\n<\/pre>\n<p>In this example we specify the background transparency to the color &#8220;white&#8221;, then we flatten the image. \u00a0The thing about JPG that is worth mentioning is that it is a lossy compression algorithm. \u00a0Since I don&#8217;t want to loose any image data, I specify that no compression be used and that the quality be %100 for all options.<\/p>\n<p>Now that the images are available in the correct format, we can continue on to process them into video streams. \u00a0This command should do the trick.<\/p>\n<pre>\r\n<code>\r\nmencoder mf:\/\/*.jpg -mf fps=60 -o DestinationVideo.avi -ovc lavc -lavcopts vcodec=mpeg4\r\n<\/code>\r\n<\/pre>\n<p>In this command we&#8217;re taking all of the JPG files in the current directory and converting them to a MPEG4 video with the AVI extension. \u00a0The output video will be at 60 frames per second.<\/p>\n<p>With the revisited image and video creation process out of the way, I want to show a simple procedure to show a condition unique to the web scraped images. \u00a0In this next example I will plot a graph from the images. \u00a0This graph will represent day and night time conditions.<\/p>\n<p><a href=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2015\/01\/FileSizePlot.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-1712\" src=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2015\/01\/FileSizePlot-300x138.png\" alt=\"FileSizePlot\" width=\"300\" height=\"138\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/FileSizePlot-300x138.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/FileSizePlot-1024x472.png 1024w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/FileSizePlot-100x46.png 100w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/FileSizePlot-150x69.png 150w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/FileSizePlot-200x92.png 200w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/FileSizePlot-450x207.png 450w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/FileSizePlot-600x277.png 600w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/FileSizePlot-900x415.png 900w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/FileSizePlot.png 1041w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>This graph was created using the file sizes of each image over a period of time. \u00a0There are\u00a0discrepancies with this method, but it does reveal something interesting. \u00a0The image compression is greater when most of the image scene is uniform. \u00a0In contrast, when the image scene has a diversity of pixel values, the compression is lower. \u00a0In the graph above, we can also see the peak variations. \u00a0This is an attribute of weather. \u00a0During overcast days, the pixel diversity is lower than it is on clear sunny days.<\/p>\n<p>At this point you may be asking yourself, what does this have to do with ImageMagick? \u00a0The problem with the data analysis we&#8217;ve done so far is it lacks detail. \u00a0The data isn&#8217;t a direct observation of a condition\u00a0and this\u00a0is a valid concern. \u00a0We only have a graph of the file sizes over time, which is an observation of the JPG compression. \u00a0There are several conditions that will influence the file size. \u00a0GIF and PNG compression will not show the same variations of file size, so our earlier method will not work. \u00a0 With ImageMagick, we can make observations at the pixel level. \u00a0Here is were the magic is.<\/p>\n<p>In this image, we can visually see the road conditions plotted. \u00a0It&#8217;s simple and to the point. \u00a0However, we can not tell how these conditions change over time.<\/p>\n<p><a href=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2015\/01\/WSDOT_Bridges_20150112200002.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-1717\" src=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2015\/01\/WSDOT_Bridges_20150112200002-300x220.gif\" alt=\"WSDOT_Bridges_20150112200002\" width=\"300\" height=\"220\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WSDOT_Bridges_20150112200002-300x220.gif 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WSDOT_Bridges_20150112200002-100x73.gif 100w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WSDOT_Bridges_20150112200002-150x110.gif 150w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WSDOT_Bridges_20150112200002-200x147.gif 200w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WSDOT_Bridges_20150112200002-450x330.gif 450w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WSDOT_Bridges_20150112200002-600x440.gif 600w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>This is a\u00a0problem that ImageMagick will solve for us. \u00a0We will be able to use ImageMagick to\u00a0plot a\u00a0condition of a specific point over time.<\/p>\n<p>The first step in the process is to get the image then select the pixels to analize. \u00a0In this example, we want to quantify the volume of west bound traffic on the 520 bridge. The image scrapped from the WSDOT website has a dimension of 780 x 572 and is in\u00a0a GIF format. The pixels that contain data pertinent\u00a0to our needs\u00a0are\u00a0located at 238\u00a0x\u00a0235 and they span 4 x 4. With that information, we can crop the image into a new file that only contains the pixels we what data from. One thing to keep in mind is JPG crops are simple. GIF images on the otherhand can pose issues if the transparency layer is not removed. For that reason, I have the same command listed below to show the differences.<\/p>\n<pre>\r\n<code>\r\nconvert -crop 4x4+238+235 InputImage.jpg CroppedOutputImage.jpg\r\nconvert -crop 4x4+238+235 +repage InputImage.gif CroppedOutputImage.gif\r\n<\/code>\r\n<\/pre>\n<p>Now that we have the pixels isolated, we can run a histogram analysis on the cropped image. Here is the command to do that.<\/p>\n<pre>\r\n<code>\r\nconvert CroppedOutputImage.gif -format %c histogram:info:TextFile.txt\r\n<\/code>\r\n<\/pre>\n<p>This generates a text file that will tally the number of pixels that are of a certain color. We are looking for 6 specific colors which are green, yellow, red, black, grey, and white. The histogram report will come back with the following text.<\/p>\n<pre>\r\n<code>\r\n16: (32,224,64) #20E040 srgb(32,224,64)\r\n<\/code>\r\n<\/pre>\n<p>From here we can see that all 16 of the pixels are the same color, #20E040, which is green. Now that we have a text based reading of the pixels, we can associate it with a value. This will involve some <a href=\"http:\/\/robots.thoughtbot.com\/sed-102-replace-in-place\" target=\"_blank\">text parsing<\/a> and processing, something of which python\u00a0is well suited for.<\/p>\n<pre>\r\n<code>\r\nmyfile = open(\"\/home\/pi\/cacti_scripts\/TextFile.txt\").read().replace('\\n','')\r\ncutfile = myfile.partition('#')[2]\r\nhead, sep, tail = cutfile.partition(' ')\r\ntext_file = open(\"\/home\/pi\/cacti_scripts\/HEXReading.txt\", \"w\")\r\ntext_file.write(head)\r\ntext_file.close()\r\n<\/code>\r\n<\/pre>\n<p>The great thing about processing the text information is now we can port it over to Cacti to graph over time. To do that, we&#8217;ll run a text format script in python and setup our output so Cacti can read it.<\/p>\n<pre>\r\n<code>\r\nif head in ('000000'):\r\n      cactivalue = open(\"\/home\/pi\/cacti_scripts\/HEXReading.txt\").read().replace('000000','traffic:4')\r\nelif head in ('FF0000'):\r\n      cactivalue = open(\"\/home\/pi\/cacti_scripts\/HEXReading.txt\").read().replace('FF0000','traffic:3')\r\nelif head in ('FFFF00'):\r\n      cactivalue = open(\"\/home\/pi\/cacti_scripts\/HEXReading.txt\").read().replace('FFFF00','traffic:2')\r\nelif head in ('20E040'):\r\n      cactivalue = open(\"\/home\/pi\/cacti_scripts\/HEXReading.txt\").read().replace('20E040','traffic:1')\r\nelse:\r\n      cactivalue = 'traffic:0'\r\n\r\nprint cactivalue\r\n<\/code>\r\n<\/pre>\n<p>Now is a perfect time to break away from image processing and revisit Cacti. You can view my <a href=\"http:\/\/192.168.3.4\/?p=1288\" target=\"_blank\">earlier posts on Cacti<\/a>, especially on the light sensor readings using RPi. Here we&#8217;ll need to create a new device and data source to graph the data. \u00a0In that post I reference another blog that did the leg work, you can find the document <a href=\"http:\/\/jartweb.net\/blog\/wp-content\/uploads\/2013\/12\/Raspberry-Pi-Logger-with-LCD.pdf\" target=\"_blank\">here<\/a>.<\/p>\n<p>First we&#8217;ll create our Data Input Method by opening the Cacti console on our RPi and selecting DIM under the Collection Methods section. \u00a0Click the Add link on the upper right corner to start a new DIM. \u00a0Enter the name of the DIM, we&#8217;ll use &#8220;West Bound 520&#8221;. \u00a0Set input type to &#8220;Script\/Command&#8221;. \u00a0Then we&#8217;ll enter the input string which is the path and python script that Cacti will use to get the current reading. \u00a0Yours may differ, my input string is &#8220;\/var\/www\/cacti\/scripts\/wb520.py&#8221; \u00a0Clicking Create will add some more options we&#8217;ll need to enter before continuing on.<\/p>\n<p>In the Output Fields we&#8217;ll enter &#8220;traffic&#8221; for the Field Output, since this will be the reading identifier which originates from our &#8220;wb520.py&#8221; script. \u00a0Next we can enter a friendly name, which we&#8217;ll use &#8220;WB520Traffic&#8221;. \u00a0Now we are done with that in Cacti, lets go on to our Data Sources.<\/p>\n<p>Click Data Sources from the Management section and click Add in the top right. \u00a0Leave the Data Template blank and choose the RPi from the pull down. \u00a0It should have either 127.0.0.1 or the IP you assigned to it in parenthesis. \u00a0Clicking the Create button will bring us to more options.<\/p>\n<p>We&#8217;ll enter in &#8220;WB520Data&#8221; for the Data Source name. \u00a0The Data Source Path should be left blank. The Data Input Method is the script we created, &#8220;West Bound 520&#8221;. \u00a0We&#8217;ll leave the step at 300 seconds, since the images won&#8217;t be updated any faster.<\/p>\n<p>The internal Data Source Name has to match the entry we set in the Output Field and &#8220;wb520.py&#8221; script. \u00a0In our case, this is &#8220;traffic&#8221;. \u00a0Lastly, we enter our max and min values we expect to read followed by the heartbeat setting. \u00a0The heartbeat is a value in seconds that will let Cacti know when to enter a reading of unknown if that much time has passed since a valid reading.<\/p>\n<p>Now our Output Field will be visible, be sure it show &#8220;traffic &#8211; WB520&#8221;. \u00a0Click Save and now we&#8217;re ready to setup our graph template.<\/p>\n<p>Click Graph Management, then the Add link at the top right. \u00a0Choose None from the Selected Graph Template and for the Host choose the RPi from the pull down. \u00a0We&#8217;ll set the title to &#8220;West Bound 520 Traffic&#8221;. \u00a0The next thing\u00a0to set\u00a0is the Vertical Label, which we&#8217;ll put &#8220;intensity&#8221;. \u00a0We&#8217;re done, so we can click Create.<\/p>\n<p>Now we should have a Graph Items section added to the window.Lets start by clicking Add in that new section. \u00a0Now we can select\u00a0our data source, in our case it is &#8220;WB520Data (traffic)&#8221;. \u00a0I&#8217;ll be using &#8220;C00000&#8221; for the graph color. \u00a0Next we&#8217;ll choose &#8220;AREA&#8221; as the graph type. \u00a0The only other thing I&#8217;ll set is &#8220;Traffic&#8221; in the Text Format section, which is used in the legend.<\/p>\n<p>That&#8217;s it! \u00a0 Now we have data being entered into Cacti&#8230;woohoo!<\/p>\n<p><a href=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2015\/01\/WB520Graph2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-1761\" src=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2015\/01\/WB520Graph2.png\" alt=\"WB520Graph\" width=\"595\" height=\"210\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WB520Graph2.png 595w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WB520Graph2-300x106.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WB520Graph2-100x35.png 100w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WB520Graph2-150x53.png 150w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WB520Graph2-200x71.png 200w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/WB520Graph2-450x159.png 450w\" sizes=\"auto, (max-width: 595px) 100vw, 595px\" \/><\/a>Here is the complete source script that Cacti uses to download, process, and read.<\/p>\n<pre>\r\n<code>\r\n#!\/usr\/bin\/python\r\n\r\nimport urllib\r\nimport os\r\n\r\nurllib.urlretrieve(\"http:\/\/images.wsdot.wa.gov\/nwflow\/flowmaps\/bridges.gif\", filename=\"\/home\/pi\/cacti_scripts\/WSDOT_Bridges.gif\")\r\n\r\nos.system(\"convert -crop 4x4+238+235 +repage \/home\/pi\/cacti_scripts\/WSDOT_Bridges.gif \/home\/pi\/cacti_scripts\/cropped.gif\")\r\nos.system(\"convert \/home\/pi\/cacti_scripts\/cropped.gif -format %c histogram:info:\/home\/pi\/cacti_scripts\/TextFile.txt\")\r\n\r\nmyfile = open(\"\/home\/pi\/cacti_scripts\/TextFile.txt\").read().replace('\\n','')\r\ncutfile = myfile.partition('#')[2]\r\nhead, sep, tail = cutfile.partition(' ')\r\ntext_file = open(\"\/home\/pi\/cacti_scripts\/HEXReading.txt\", \"w\")\r\ntext_file.write(head)\r\ntext_file.close()\r\n\r\nif head in ('000000'):\r\n      cactivalue = open(\"\/home\/pi\/cacti_scripts\/HEXReading.txt\").read().replace('000000','traffic:4')\r\nelif head in ('FF0000'):\r\n      cactivalue = open(\"\/home\/pi\/cacti_scripts\/HEXReading.txt\").read().replace('FF0000','traffic:3')\r\nelif head in ('FFFF00'):\r\n      cactivalue = open(\"\/home\/pi\/cacti_scripts\/HEXReading.txt\").read().replace('FFFF00','traffic:2')\r\nelif head in ('20E040'):\r\n      cactivalue = open(\"\/home\/pi\/cacti_scripts\/HEXReading.txt\").read().replace('20E040','traffic:1')\r\nelse:\r\n      cactivalue = 'traffic:0'\r\n\r\nprint cactivalue\r\n<\/code>\r\n<\/pre>\n<p>Since the grueling work is now behind us, we can move forward to the last item, which will be video from enhanced images. \u00a0We&#8217;ll do a simple normalize command in ImageMagick to create a new series of images. \u00a0Next we&#8217;ll process these to create a video stream. \u00a0Lets wrap this topic up. \u00a0Here is the command to run.<\/p>\n<pre>\r\n<code>\r\nconvert -normalize InputImage.jpg OutputImage.jpg\r\n<\/code>\r\n<\/pre>\n<p>In my archive, I have around 10,000 images to process through. \u00a0It\u00a0took\u00a0some time to complete, 8 hours to be more precise. \u00a0Once they were done normalizing, I went ahead and processed them into a video stream. \u00a0Here are the results. \u00a0The left is the normalized images and the right are the original images.<\/p>\n<p><iframe loading=\"lazy\" src=\"\/\/www.youtube.com\/embed\/Fz-23axUzuM\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<p><strong>Relations &#8211; a clearer understanding of what is <\/strong><\/p>\n<p>We have been briefly introduced to the subject of image processing. \u00a0The work of John Cristy at DuPont in the mid 1980s and the agreed release of it to\u00a0usenet in the early 90s has given us empowerment. \u00a0We lucked out. \u00a0No one was obliged to do this work for the greater good, unlike the agreed settlement made by ATT during its monopoly breakup.<\/p>\n<p>Even so, some misconceptions about image processing persist. \u00a0The name of Imagemagick is appropriate. \u00a0It is magic to the casual observer. \u00a0This give fruit to stories of how it can be used and the results it can provide. \u00a0You will see exaggerations on both sides to the capabilities and limitations of image processing. \u00a0Most of these can be\u00a0discredited by observing examples that contradict the claims. \u00a0Even though\u00a0the claims are more readily available than the disproving facts, you have a way to validate. \u00a0With a RPi, you can test the limits of what is possible.<\/p>\n<p>If you find this subject interesting, I would suggest you read <a href=\"http:\/\/keithwiley.com\/astroPhotography\/imageStacking.shtml\" target=\"_blank\">this short write<\/a> up by\u00a0Keith Wiley. \u00a0You may also find <a href=\"http:\/\/www.fmwconcepts.com\/imagemagick\/retinex\/\" target=\"_blank\">this example<\/a> from Fred Weinhaus insightful\u00a0on the whole business of image processing. \u00a0One item that I&#8217;d like to include is a Windows program that will enhance images using stacking\u00a0called <a href=\"http:\/\/www.astronomie.be\/registax\/index.html\" target=\"_blank\">RegiStax<\/a>. \u00a0Funny thing is ImageMagick can do the same thing with this series of commands.<\/p>\n<pre>\r\n<code>\r\nconvert *.jpg -evaluate-sequence median OutputFile1.jpg\r\nconvert -unsharp 1.2x1.2+5+0 OutputFile1.jpg OutputFile2.jpg\r\nconvert -normalize OutputFile2.jpg OutputFileFinal.jpg\r\n<\/code>\r\n<\/pre>\n<p>Here is a comparison of the original next to the ImageMagick and RegiStax processed images. \u00a0You be the judge.<\/p>\n<p><a href=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2015\/01\/IM_RegiStax_Original.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-large wp-image-1749\" src=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2015\/01\/IM_RegiStax_Original-1024x256.jpg\" alt=\"IM_RegiStax_Original\" width=\"605\" height=\"151\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/IM_RegiStax_Original-1024x256.jpg 1024w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/IM_RegiStax_Original-300x75.jpg 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/IM_RegiStax_Original-100x25.jpg 100w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/IM_RegiStax_Original-150x38.jpg 150w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/IM_RegiStax_Original-200x50.jpg 200w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/IM_RegiStax_Original-450x113.jpg 450w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/IM_RegiStax_Original-600x150.jpg 600w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/IM_RegiStax_Original-900x225.jpg 900w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2015\/01\/IM_RegiStax_Original.jpg 1919w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/a><\/p>\n<p>These sites were key to getting me to try it in ImageMagick. \u00a0The first explained <a href=\"http:\/\/blog.patdavid.net\/2013\/05\/noise-removal-in-photos-with-median_6.html\" target=\"_blank\">averaging<\/a>, the next explained <a href=\"http:\/\/redskiesatnight.com\/2005\/04\/06\/sharpening-using-image-magick\/\" target=\"_blank\">unsharping<\/a>. \u00a0I did my normalize trick at the end.<\/p>\n<p><strong>Summary &#8211; it sure can do a lot<\/strong><\/p>\n<p>In this post I covered some basic image processing that can be performed on the RPi using ImageMagick. \u00a0The ability of the RPi to run this processing using python is remarkable. \u00a0The data extracted\u00a0from the images can be used for other applications.<\/p>\n<p>We covered how to convert\u00a0images into a format that\u00a0allowed us to\u00a0create a video from the image source. \u00a0Next we showed how image file size changes due to visual conditions. \u00a0Based on the unpredictable results of this observation method, we then covered pixel analysis. \u00a0We stepped through the process of gathering, isolating, evaluating, and plotting the results using Cacti. \u00a0Then we revisited our video processing method, but enhanced the images prior to creating the video. \u00a0Finally, we covered more enhancement options that ImageMagick offers.<\/p>\n<p>In upcoming posts, we&#8217;ll cover how to crate an overlay of data on images. \u00a0This will be useful in HUD applications to display telemetry data in real time, which is a stepping stone to augmented reality.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction &#8211; processing images with ImageMagick I first\u00a0posted about ImageMagick in early June, last year. \u00a0Then late\u00a0November, I covered the steps to install it and use it on RPi. \u00a0The features of ImageMagick are fairly extensive, I won&#8217;t go into all of them here. \u00a0As a guide, I recommend\u00a0Michael Still&#8217;s book titled &#8220;The Definitive Guide to ImageMagick&#8221; through APress publishing. \u00a0For additional information, you may want to look at\u00a0Sohail Salehi&#8217;s book titled &#8220;ImageMagick Tricks&#8221; from Packt Publishing. ImageMagick\u00a0is defined on&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.cloudacm.com\/?p=1694\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,10,6,3],"tags":[],"class_list":["post-1694","post","type-post","status-publish","format-standard","hentry","category-computer-vision","category-data-mining","category-raspberry-pi","category-rd"],"_links":{"self":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/1694","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1694"}],"version-history":[{"count":59,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/1694\/revisions"}],"predecessor-version":[{"id":1908,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/1694\/revisions\/1908"}],"wp:attachment":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1694"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1694"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1694"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}