{"id":2625,"date":"2010-12-10T15:38:43","date_gmt":"2010-12-10T15:38:43","guid":{"rendered":"https:\/\/blogs.mathworks.com\/pick\/2010\/12\/10\/video-player-for-your-frame-based-processing\/"},"modified":"2010-12-10T15:38:43","modified_gmt":"2010-12-10T15:38:43","slug":"video-player-for-your-frame-based-processing","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/pick\/2010\/12\/10\/video-player-for-your-frame-based-processing\/","title":{"rendered":"Video player for your frame-based processing"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p><a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/15007\">Jiro<\/a>'s pick this week is <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/29544-figure-to-play-and-analyze-videos-with-custom-plots-on-top\"><tt>videofig<\/tt><\/a> by <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/54393\">Joao Henriques<\/a>.\r\n      <\/p>\r\n      <p>If you're interested in frame-based visualization, here's a must-have function. You may have video frames that you want to\r\n         analyze, and do some processing and visualization on every frame. Once that's all done, you may want to be able to quickly\r\n         flip through the frames or view them as a movie. Joao's <tt>videofig<\/tt> allows you to do just that.\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#1\">Setting up your function for processing each frame<\/a><\/li>\r\n         <li><a href=\"#3\">Setting up videofig<\/a><\/li>\r\n         <li><a href=\"#4\">Control playback<\/a><\/li>\r\n         <li><a href=\"#5\">See examples of good MATLAB coding practices<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Setting up your function for processing each frame<a name=\"1\"><\/a><\/h3>\r\n   <p>You first set up your function that would be applied to any particular frame. This function should include any visualization\r\n      as well. Here's an example that performs edge detection and displays an overlayed image of a frame from a video object. One\r\n      of the input arguments must be the frame number.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">type <span style=\"color: #A020F0\">redraw<\/span><\/pre><pre style=\"font-style:oblique\">\r\nfunction redraw(frame, vidObj)\r\n% REDRAW  Process a particular frame of the video\r\n%   REDRAW(FRAME, VIDOBJ)\r\n%       frame  - frame number to process\r\n%       vidObj - VideoReader object\r\n\r\n% Read frame\r\nf = vidObj.read(frame);\r\n\r\n% Get edge\r\nf2 = edge(rgb2gray(f), 'canny');\r\n\r\n% Overlay edge on original image\r\nf3 = bsxfun(@plus, f,  uint8(255*f2));\r\n\r\n% Display\r\nimage(f3); axis image off\r\n\r\nend\r\n\r\n<\/pre><p><i>Note: The functions <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/toolbox\/images\/ref\/edge.html\"><tt>edge<\/tt><\/a> and <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/toolbox\/images\/ref\/rgb2gray.html\"><tt>rgb2gray<\/tt><\/a> requires <a href=\"https:\/\/www.mathworks.com\/products\/image\/\">Image Processing Toolbox<\/a>.<\/i><\/p>\r\n   <h3>Setting up videofig<a name=\"3\"><\/a><\/h3>\r\n   <p><tt>videofig<\/tt> takes two input arguments:\r\n   <\/p>\r\n   <div>\r\n      <ul>\r\n         <li>Total number of frames<\/li>\r\n         <li>Function handle to a function that should be called for each frame. This function should only take one input argument, \"frame\r\n            number\". If your function takes additional arguments, use an <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/matlab_prog\/f4-70115.html\">anonymous function<\/a> as shown below.\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p><i>Note: \"rhinos.avi\" is a movie file that ships with Image Processing Toolbox. <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/videoreaderclass.html\"><tt>VideoReader<\/tt><\/a> is a new class introduced in R2010b that replaces <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/mmreaderclass.html\"><tt>mmreader<\/tt><\/a> (introduced in R2007b). If you are using an older version (pre-R2010b), replace <tt>VideoReader<\/tt> with <tt>mmreader<\/tt>.<\/i><\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">vid = VideoReader(<span style=\"color: #A020F0\">'rhinos.avi'<\/span>);\r\n\r\n<span style=\"color: #228B22\">% Set up video figure window<\/span>\r\nvideofig(vid.NumberOfFrames, @(frm) redraw(frm, vid));\r\n\r\n<span style=\"color: #228B22\">% Display initial frame<\/span>\r\nredraw(1, vid);<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/pick\/jiro\/potw_VideoFigure\/potw_VideoFigure_01.png\"> <h3>Control playback<a name=\"4\"><\/a><\/h3>\r\n   <p>That's it! You now have an interactive video player that allows you to view the frames. As you can see, the figure has a scroll\r\n      bar at the bottom that you can click and drag. You can also control the video via the keyboard, such as with the arrow keys.\r\n   <\/p>\r\n   <p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/pick\/jiro\/potw_VideoFigure\/videofig_animation.gif\"> <\/p>\r\n   <h3>See examples of good MATLAB coding practices<a name=\"5\"><\/a><\/h3>\r\n   <p>I would also like to point out some of Joao's nice coding practices.<\/p>\r\n   <div>\r\n      <ul>\r\n         <li>Input argument validation to ensure proper operation of the function. He uses <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/assert.html\"><tt>assert<\/tt><\/a> to check for argument conditions. I would also recommend taking a look at <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/inputparser.html\"><tt>inputParser<\/tt><\/a> and <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/validateattributes.html\"><tt>validateattributes<\/tt><\/a> for this purpose.\r\n         <\/li>\r\n         <li><a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/matlab_prog\/f4-39683.html\">Nested functions<\/a> to manage data. These are especially useful when you want to change the states as the user interacts with the tool.\r\n         <\/li>\r\n         <li><a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/timer.html\">Timer<\/a> object to control playback of video. I find timers (as opposed to loops) to be more useful for animation\/playback applications,\r\n            since I can easily stop the animation by stopping the timer.\r\n         <\/li>\r\n         <li><a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/math\/f2-14889.html\">Function handles<\/a> for the redrawing function. This is the suggested method for providing functions as inputs, instead of passing in the string\r\n            of the function name. Loren has a lot of useful posts on her <a href=\"https:\/\/blogs.mathworks.com\/loren\/category\/function-handles\/\">blog<\/a>.\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p><b>Comments<\/b><\/p>\r\n   <p>Let us know what you think <a href=\"https:\/\/blogs.mathworks.com\/pick\/?p=2625#respond\">here<\/a> or leave a <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/29544-figure-to-play-and-analyze-videos-with-custom-plots-on-top#comments\">comment<\/a> for Joao.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_2046157bd3e7448cb7cf151c84d06eaa() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='2046157bd3e7448cb7cf151c84d06eaa ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 2046157bd3e7448cb7cf151c84d06eaa';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        author = 'Jiro Doke';\r\n        copyright = 'Copyright 2010 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n      \r\n      d.title = title + ' (MATLAB code)';\r\n      d.close();\r\n      }   \r\n      \r\n-->\r\n<\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_2046157bd3e7448cb7cf151c84d06eaa()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code \r\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.11<br><\/p>\r\n<\/div>\r\n<!--\r\n2046157bd3e7448cb7cf151c84d06eaa ##### SOURCE BEGIN #####\r\n%%\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/15007\r\n% Jiro>'s pick this week is\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/29544-figure-to-play-and-analyze-videos-with-custom-plots-on-top\r\n% |videofig|> by\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/54393 Joao\r\n% Henriques>.\r\n%\r\n% If you're interested in frame-based visualization, here's a must-have\r\n% function. You may have video frames that you want to analyze, and do some\r\n% processing and visualization on every frame. Once that's all done, you\r\n% may want to be able to quickly flip through the frames or view them as a\r\n% movie. Joao's |videofig| allows you to do just that.\r\n\r\n%% Setting up your function for processing each frame\r\n% You first set up your function that would be applied to any particular\r\n% frame. This function should include any visualization as well. Here's an\r\n% example that performs edge detection and displays an overlayed image of a\r\n% frame from a video object. One of the input arguments must be the frame\r\n% number.\r\n\r\ntype redraw\r\n\r\n%%\r\n% _Note: The functions\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/toolbox\/images\/ref\/edge.html\r\n% |edge|> and\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/toolbox\/images\/ref\/rgb2gray.html\r\n% |rgb2gray|> requires <https:\/\/www.mathworks.com\/products\/image\/ Image\r\n% Processing Toolbox>._\r\n\r\n%% Setting up |videofig|\r\n% |videofig| takes two input arguments:\r\n%\r\n% * Total number of frames\r\n% * Function handle to a function that should be called for each frame.\r\n% This function should only take one input argument, \"frame number\". If\r\n% your function takes additional arguments, use an\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/matlab_prog\/f4-70115.html\r\n% anonymous function> as shown below.\r\n%\r\n% _Note: \"rhinos.avi\" is a movie file that ships with Image Processing\r\n% Toolbox.\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/videoreaderclass.html\r\n% |VideoReader|> is a new class introduced in R2010b that replaces\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/mmreaderclass.html\r\n% |mmreader|> (introduced in R2007b). If you are using an older version\r\n% (pre-R2010b), replace |VideoReader| with |mmreader|._\r\n\r\nvid = VideoReader('rhinos.avi');\r\n\r\n% Set up video figure window\r\nvideofig(vid.NumberOfFrames, @(frm) redraw(frm, vid));\r\n\r\n% Display initial frame\r\nredraw(1, vid);\r\n\r\n%% Control playback\r\n% That's it! You now have an interactive video player that allows you\r\n% to view the frames. As you can see, the figure has a scroll bar at the\r\n% bottom that you can click and drag. You can also control the video via\r\n% the keyboard, such as with the arrow keys.\r\n%\r\n% <<videofig_animation.gif>>\r\n\r\n%% See examples of good MATLAB coding practices\r\n% I would also like to point out some of Joao's nice coding practices.\r\n%\r\n% * Input argument validation to ensure proper operation of the function.\r\n% He uses\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/assert.html\r\n% |assert|> to check for argument conditions. I would also recommend taking\r\n% a look at\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/inputparser.html\r\n% |inputParser|> and\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/validateattributes.html\r\n% |validateattributes|> for this purpose.\r\n% * <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/matlab_prog\/f4-39683.html\r\n% Nested functions> to manage data. These are especially useful when you\r\n% want to change the states as the user interacts with the tool.\r\n% * <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/ref\/timer.html\r\n% Timer> object to control playback of video. I find timers (as opposed to\r\n% loops) to be more useful for animation\/playback applications, since I can\r\n% easily stop the animation by stopping the timer.\r\n% * <https:\/\/www.mathworks.com\/help\/releases\/R2010b\/techdoc\/math\/f2-14889.html\r\n% Function handles> for the redrawing function. This is the suggested\r\n% method for providing functions as inputs, instead of passing in the\r\n% string of the function name. Loren has a lot of useful posts on her\r\n% <https:\/\/blogs.mathworks.com\/loren\/category\/function-handles\/ blog>.\r\n%\r\n% *Comments*\r\n%\r\n% Let us know what you think\r\n% <https:\/\/blogs.mathworks.com\/pick\/?p=2625#respond here> or leave a\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/29544-figure-to-play-and-analyze-videos-with-custom-plots-on-top#comments comment> for Joao.\r\n\r\n##### SOURCE END ##### 2046157bd3e7448cb7cf151c84d06eaa\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n      Jiro's pick this week is videofig by Joao Henriques.\r\n      \r\n      If you're interested in frame-based visualization, here's a must-have function. You may have video frames that you... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/pick\/2010\/12\/10\/video-player-for-your-frame-based-processing\/\">read more >><\/a><\/p>","protected":false},"author":35,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/2625"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/users\/35"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/comments?post=2625"}],"version-history":[{"count":0,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/2625\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/media?parent=2625"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/categories?post=2625"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/tags?post=2625"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}