GSoC 2016 - Adding ALIASES for tutorial (#7041)
authorCartucho <joaocartuchoo@gmail.com>
Thu, 15 Dec 2016 12:32:12 +0000 (12:32 +0000)
committerMaksim Shabunin <maksim.shabunin@gmail.com>
Thu, 15 Dec 2016 12:32:12 +0000 (15:32 +0300)
* GSoC 2016 - Adding toggle files to be used by tutorials.

Add a toggle option for tutorials.
* adds a button on the HTML tutorial pages to switch between blocks
* the default option is for languages: one can write a block
for C++ and another one for Python without re-writing the tutorial

Add aliases to the doxyfile.
* adding alises to make a link to previous and next tutorial.
* adding alias to specify the toggle options in the tutorials index.
* adding alias to add a youtube video directly from link.

Add a sample tutorial (mat_mask_opertaions) using the developed aliases:
* youtube alias
* previous and next tutorial alias
* buttons
* languages info for tutorial table of content
* code referances with snippets (and associated sample code files)

* Removing the automatic ordering.
Adding specific toggles for cpp, java and python.
Move all the code to the footer / header and Doxyfile.
Updating documentation.

13 files changed:
doc/Doxyfile.in
doc/footer.html
doc/header.html
doc/mymath.js
doc/tutorials/core/mat-mask-operations/mat_mask_operations.markdown
doc/tutorials/core/table_of_content_core.markdown
doc/tutorials/introduction/documenting_opencv/documentation_tutorial.markdown
samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp
samples/cpp/tutorial_code/introduction/documentation/documentation.cpp [new file with mode: 0644]
samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java [new file with mode: 0644]
samples/java/tutorial_code/introduction/documentation/Documentation.java [new file with mode: 0644]
samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py [new file with mode: 0644]
samples/python/tutorial_code/introduction/documentation/documentation.py [new file with mode: 0644]

index f0c15e0..2e4ac70 100644 (file)
@@ -31,10 +31,17 @@ MULTILINE_CPP_IS_BRIEF = NO
 INHERIT_DOCS           = YES
 SEPARATE_MEMBER_PAGES  = NO
 TAB_SIZE               = 4
-ALIASES                =
+ALIASES               += add_toggle{1}="@htmlonly[block] <div class='newInnerHTML'>\1</div><div> <script type="text/javascript"> addToggle(); </script>@endhtmlonly"
+ALIASES               += add_toggle_cpp="@htmlonly[block] <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'>@endhtmlonly"
+ALIASES               += add_toggle_java="@htmlonly[block] <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'>@endhtmlonly"
+ALIASES               += add_toggle_python="@htmlonly[block] <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'>@endhtmlonly"
+ALIASES               += end_toggle="@htmlonly[block] </div> @endhtmlonly"
+ALIASES               += prev_tutorial{1}="**Prev  Tutorial:** \ref \1 \n"
+ALIASES               += next_tutorial{1}="**Next  Tutorial:** \ref \1 \n"
+ALIASES               += youtube{1}="@htmlonly[block]<div align='center'><iframe title='my title' width='560' height='349' src='http://www.youtube.com/embed/\1?rel=0' frameborder='0' align='middle' allowfullscreen></iframe></div>@endhtmlonly"
 TCL_SUBST              =
 OPTIMIZE_OUTPUT_FOR_C  = NO
-OPTIMIZE_OUTPUT_JAVA   = NO
+OPTIMIZE_OUTPUT_JAVA   = YES
 OPTIMIZE_FOR_FORTRAN   = NO
 OPTIMIZE_OUTPUT_VHDL   = NO
 EXTENSION_MAPPING      =
index e9a2ed7..c636144 100644 (file)
@@ -17,5 +17,74 @@ $generatedby &#160;<a href="http://www.doxygen.org/index.html">
 </a> $doxygenversion
 </small></address>
 <!--END !GENERATE_TREEVIEW-->
+<script type="text/javascript">
+//<![CDATA[
+function addButton(label, buttonName) {
+    var b = document.createElement("BUTTON");
+    b.innerHTML = buttonName;
+    b.setAttribute('class', 'toggleable_button label_' + label);
+    b.onclick = function() {
+        $('.toggleable_button').css({
+            border: '2px outset',
+            'border-radius': '4px'
+        });
+        $('.toggleable_button.label_' + label).css({
+            border: '2px inset',
+            'border-radius': '4px'
+        });
+        $('.toggleable_div').css('display', 'none');
+        $('.toggleable_div.label_' + label).css('display', 'block');
+    };
+    b.style.border = '2px outset';
+    b.style.borderRadius = '4px';
+    b.style.margin = '2px';
+    return b;
+}
+function buttonsToAdd($elements, $heading, $type) {
+    if ($elements.length === 0) {
+        $elements = $("" + $type + ":contains(" + $heading.html() + ")").parent().prev("div.newInnerHTML");
+    }
+    var arr = jQuery.makeArray($elements);
+    var seen = {};
+    arr.forEach(function(e) {
+        var txt = e.innerHTML;
+        if (!seen[txt]) {
+            $button = addButton(e.title, txt);
+            if (Object.keys(seen).length == 0) {
+                var linebreak1 = document.createElement("br");
+                var linebreak2 = document.createElement("br");
+                ($heading).append(linebreak1);
+                ($heading).append(linebreak2);
+            }
+            ($heading).append($button);
+            seen[txt] = true;
+        }
+    });
+    return;
+}
+$("h2").each(function() {
+    $heading = $(this);
+    $smallerHeadings = $(this).nextUntil("h2").filter("h3").add($(this).nextUntil("h2").find("h3"));
+    if ($smallerHeadings.length) {
+        $smallerHeadings.each(function() {
+            var $elements = $(this).nextUntil("h3").filter("div.newInnerHTML");
+            buttonsToAdd($elements, $(this), "h3");
+        });
+    } else {
+        var $elements = $(this).nextUntil("h2").filter("div.newInnerHTML");
+        buttonsToAdd($elements, $heading, "h2");
+    }
+});
+$(".toggleable_button").first().click();
+var $clickDefault = $('.toggleable_button.label_python').first();
+if ($clickDefault.length) {
+    $clickDefault.click();
+}
+$clickDefault = $('.toggleable_button.label_cpp').first();
+if ($clickDefault.length) {
+    $clickDefault.click();
+}
+//]]>
+</script>
 </body>
 </html>
index bbaf1d5..94d42b4 100644 (file)
@@ -54,4 +54,34 @@ $extrastylesheet
 </table>
 </div>
 <!--END TITLEAREA-->
+<script type="text/javascript">
+//<![CDATA[
+function getLabelName(innerHTML) {
+    var str = innerHTML.toLowerCase();
+    // Replace all '+' with 'p'
+    str = str.split('+').join('p');
+    // Replace all ' ' with '_'
+    str = str.split(' ').join('_');
+    // Replace all '#' with 'sharp'
+    str = str.split('#').join('sharp');
+    // Replace other special characters with 'ascii' + code
+    for (var i = 0; i < str.length; i++) {
+        var charCode = str.charCodeAt(i);
+        if (!(charCode == 95 || (charCode > 96 && charCode < 123) || (charCode > 47 && charCode < 58)))
+            str = str.substr(0, i) + 'ascii' + charCode + str.substr(i + 1);
+    }
+    return str;
+}
+function addToggle() {
+    var $getDiv = $('div.newInnerHTML').last();
+    var buttonName = $getDiv.html();
+    var label = getLabelName(buttonName.trim());
+    $getDiv.attr("title", label);
+    $getDiv.hide();
+    $getDiv = $getDiv.next();
+    $getDiv.attr("class", "toggleable_div label_" + label);
+    $getDiv.hide();
+}
+//]]>
+</script>
 <!-- end header part -->
index df9f551..fb65fab 100644 (file)
@@ -1,4 +1,4 @@
-
+//<![CDATA[
 MathJax.Hub.Config(
 {
   TeX: {
@@ -15,3 +15,4 @@ MathJax.Hub.Config(
   }
 }
 );
+//]]>
index 980ea78..ca95243 100644 (file)
@@ -1,6 +1,9 @@
 Mask operations on matrices {#tutorial_mat_mask_operations}
 ===========================
 
+@prev_tutorial{tutorial_how_to_scan_images}
+@next_tutorial{tutorial_mat_operations}
+
 Mask operations on matrices are quite simple. The idea is that we recalculate each pixels value in
 an image according to a mask matrix (also known as kernel). This mask holds values that will adjust
 how much influence neighboring pixels (and the current pixel) have on the new pixel value. From a
@@ -25,113 +28,150 @@ the zero-zero index) on the pixel you want to calculate and sum up the pixel val
 the overlapped matrix values. It's the same thing, however in case of large matrices the latter
 notation is a lot easier to look over.
 
+@add_toggle_cpp
 Now let us see how we can make this happen by using the basic pixel access method or by using the
 @ref cv::filter2D function.
+@end_toggle
+
+@add_toggle_java
+Now let us see how we can make this happen by using the basic pixel access method or by using the
+**Imgproc.filter2D()** function.
+@end_toggle
+
+@add_toggle_python
+Now let us see how we can make this happen by using the basic pixel access method or by using the
+**cv2.filter2D()** function.
+@end_toggle
 
 The Basic Method
 ----------------
 
 Here's a function that will do this:
-@code{.cpp}
-void Sharpen(const Mat& myImage, Mat& Result)
-{
-    CV_Assert(myImage.depth() == CV_8U);  // accept only uchar images
-
-    Result.create(myImage.size(), myImage.type());
-    const int nChannels = myImage.channels();
-
-    for(int j = 1; j < myImage.rows - 1; ++j)
-    {
-        const uchar* previous = myImage.ptr<uchar>(j - 1);
-        const uchar* current  = myImage.ptr<uchar>(j    );
-        const uchar* next     = myImage.ptr<uchar>(j + 1);
-
-        uchar* output = Result.ptr<uchar>(j);
-
-        for(int i = nChannels; i < nChannels * (myImage.cols - 1); ++i)
-        {
-            *output++ = saturate_cast<uchar>(5 * current[i]
-                         -current[i - nChannels] - current[i + nChannels] - previous[i] - next[i]);
-        }
-    }
-
-    Result.row(0).setTo(Scalar(0));
-    Result.row(Result.rows - 1).setTo(Scalar(0));
-    Result.col(0).setTo(Scalar(0));
-    Result.col(Result.cols - 1).setTo(Scalar(0));
-}
-@endcode
+@add_toggle_cpp
+@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp basic_method
+
 At first we make sure that the input images data is in unsigned char format. For this we use the
 @ref cv::CV_Assert function that throws an error when the expression inside it is false.
-@code{.cpp}
-CV_Assert(myImage.depth() == CV_8U);  // accept only uchar images
+@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp 8_bit
+@end_toggle
+
+@add_toggle_java
+@snippet samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java basic_method
+
+At first we make sure that the input images data in unsigned 8 bit format.
+@snippet samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java 8_bit
+@end_toggle
+
+@add_toggle_python
+@snippet samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py basic_method
+
+At first we make sure that the input images data in unsigned 8 bit format.
+@code{.py}
+my_image = cv2.cvtColor(my_image, cv2.CV_8U)
 @endcode
+
+@end_toggle
+
 We create an output image with the same size and the same type as our input. As you can see in the
 @ref tutorial_how_to_scan_images_storing "storing" section, depending on the number of channels we may have one or more
-subcolumns. We will iterate through them via pointers so the total number of elements depends from
+subcolumns.
+
+@add_toggle_cpp
+We will iterate through them via pointers so the total number of elements depends on
 this number.
-@code{.cpp}
-Result.create(myImage.size(), myImage.type());
-const int nChannels = myImage.channels();
+@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp create_channels
+@end_toggle
+
+@add_toggle_java
+@snippet samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java create_channels
+@end_toggle
+
+@add_toggle_python
+@code{.py}
+height, width, n_channels = my_image.shape
+result = np.zeros(my_image.shape, my_image.dtype)
 @endcode
+@end_toggle
+
+@add_toggle_cpp
 We'll use the plain C [] operator to access pixels. Because we need to access multiple rows at the
 same time we'll acquire the pointers for each of them (a previous, a current and a next line). We
 need another pointer to where we're going to save the calculation. Then simply access the right
 items with the [] operator. For moving the output pointer ahead we simply increase this (with one
 byte) after each operation:
-@code{.cpp}
-for(int j = 1; j < myImage.rows - 1; ++j)
-{
-    const uchar* previous = myImage.ptr<uchar>(j - 1);
-    const uchar* current  = myImage.ptr<uchar>(j    );
-    const uchar* next     = myImage.ptr<uchar>(j + 1);
-
-    uchar* output = Result.ptr<uchar>(j);
-
-    for(int i = nChannels; i < nChannels * (myImage.cols - 1); ++i)
-    {
-        *output++ = saturate_cast<uchar>(5 * current[i]
-                     -current[i - nChannels] - current[i + nChannels] - previous[i] - next[i]);
-    }
-}
-@endcode
+@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp basic_method_loop
+
 On the borders of the image the upper notation results inexistent pixel locations (like minus one -
 minus one). In these points our formula is undefined. A simple solution is to not apply the kernel
 in these points and, for example, set the pixels on the borders to zeros:
-@code{.cpp}
-Result.row(0).setTo(Scalar(0));               // The top row
-Result.row(Result.rows - 1).setTo(Scalar(0)); // The bottom row
-Result.col(0).setTo(Scalar(0));               // The left column
-Result.col(Result.cols - 1).setTo(Scalar(0)); // The right column
-@endcode
+
+@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp borders
+@end_toggle
+
+@add_toggle_java
+We need to access multiple rows and columns which can be done by adding or subtracting 1 to the current center (i,j).
+Then we apply the sum and put the new value in the Result matrix.
+@snippet samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java basic_method_loop
+
+On the borders of the image the upper notation results in inexistent pixel locations (like (-1,-1)).
+In these points our formula is undefined. A simple solution is to not apply the kernel
+in these points and, for example, set the pixels on the borders to zeros:
+
+@snippet samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java borders
+@end_toggle
+
+@add_toggle_python
+We need to access multiple rows and columns which can be done by adding or subtracting 1 to the current center (i,j).
+Then we apply the sum and put the new value in the Result matrix.
+@snippet samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py basic_method_loop
+@end_toggle
 
 The filter2D function
 ---------------------
 
 Applying such filters are so common in image processing that in OpenCV there exist a function that
 will take care of applying the mask (also called a kernel in some places). For this you first need
-to define a *Mat* object that holds the mask:
-@code{.cpp}
-Mat kern = (Mat_<char>(3,3) <<  0, -1,  0,
-                               -1,  5, -1,
-                                0, -1,  0);
-@endcode
-Then call the @ref cv::filter2D function specifying the input, the output image and the kernell to
+to define an object that holds the mask:
+@add_toggle_cpp
+@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp kern
+
+Then call the @ref cv::filter2D function specifying the input, the output image and the kernel to
 use:
-@code{.cpp}
-filter2D(I, K, I.depth(), kern);
-@endcode
-The function even has a fifth optional argument to specify the center of the kernel, and a sixth one
-for determining what to do in the regions where the operation is undefined (borders). Using this
-function has the advantage that it's shorter, less verbose and because there are some optimization
-techniques implemented it is usually faster than the *hand-coded method*. For example in my test
-while the second one took only 13 milliseconds the first took around 31 milliseconds. Quite some
-difference.
+@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp filter2D
+
+The function even has a fifth optional argument to specify the center of the kernel, a sixth
+for adding an optional value to the filtered pixels before storing them in K and a seventh one
+for determining what to do in the regions where the operation is undefined (borders).
+@end_toggle
+
+@add_toggle_java
+@snippet samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java kern
+
+Then call the **Imgproc.filter2D()** function specifying the input, the output image and the kernel to
+use:
+@snippet samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java filter2D
+The function even has a fifth optional argument to specify the center of the kernel, a sixth
+for adding an optional value to the filtered pixels before storing them in K and a seventh one
+for determining what to do in the regions where the operation is undefined (borders).
+@end_toggle
+
+@add_toggle_python
+@snippet samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py kern
+
+Then call the **cv2.filter2D()** function specifying the input, the output image and the kernell to
+use:
+@snippet samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py filter2D
+@end_toggle
+
+This function is shorter, less verbose and, because there are some optimizations, it is usually faster
+than the *hand-coded method*. For example in my test while the second one took only 13
+milliseconds the first took around 31 milliseconds. Quite some difference.
 
 For example:
 
 ![](images/resultMatMaskFilter2D.png)
 
+@add_toggle_cpp
 You can download this source code from [here
 ](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp) or look in the
 OpenCV source code libraries sample directory at
@@ -139,9 +179,15 @@ OpenCV source code libraries sample directory at
 
 Check out an instance of running the program on our [YouTube
 channel](http://www.youtube.com/watch?v=7PF1tAU9se4) .
-
-\htmlonly
-<div align="center">
-<iframe width="560" height="349" src="https://www.youtube.com/embed/7PF1tAU9se4?hd=1" frameborder="0" allowfullscreen></iframe>
-</div>
-\endhtmlonly
+@youtube{7PF1tAU9se4}
+@end_toggle
+
+@add_toggle_java
+You can look in the OpenCV source code libraries sample directory at
+`samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java`.
+@end_toggle
+
+@add_toggle_python
+You can look in the OpenCV source code libraries sample directory at
+`samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py`.
+@end_toggle
index 99e0048..70d9c81 100644 (file)
@@ -25,6 +25,8 @@ understanding how to manipulate the images on a pixel level.
 
 -   @subpage tutorial_mat_mask_operations
 
+    *Languages:* C++, Java, Python
+
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Bernát Gábor
index f1d9f9c..c51d7be 100644 (file)
@@ -439,6 +439,83 @@ Then include this snippet into documentation:
 compatibility with the old rST documentation. But newly created samples should be included with the
 _snippet_ command, since this method is less affected by the changes in processed file.
 
+### Toggle buttons inclusion commands {#tutorial_documentation_toggle_buttons_commands_include}
+
+Toggle buttons are used to display the selected configuration (e.g. programming language, OS, IDE).
+
+To use the buttons in documentation, _add_toggle_ and _end_toggle_ commands are used.
+
+The command _add_toggle_ can be
+- general: _add_toggle{Button Name}_
+- for C++: _add_toggle_cpp_
+- for Java: _add_toggle_java_
+- for Python: _add_toggle_python_
+
+Example:
+@verbatim
+@add_toggle{Button Name}
+
+  text / code / doxygen commands
+
+@end_toggle
+@endverbatim
+
+For example using toggle buttons with text and [code](@ref tutorial_documentation_commands_include) snippets:
+
+@verbatim
+
+### Buttons Example
+
+@add_toggle_cpp
+
+   Text for C++ button
+   @snippet samples/cpp/tutorial_code/introduction/documentation/documentation.cpp hello_world
+
+@end_toggle
+
+@add_toggle_java
+
+   Text for Java button
+   @snippet samples/java/tutorial_code/introduction/documentation/Documentation.java  hello_world
+
+@end_toggle
+
+@add_toggle_python
+
+   Text for Python button
+   @snippet samples/python/tutorial_code/introduction/documentation/documentation.py hello_world
+
+@end_toggle
+
+@endverbatim
+
+Result looks like this:
+
+### Buttons Example
+
+@add_toggle_cpp
+
+   Text for C++ button
+   @snippet samples/cpp/tutorial_code/introduction/documentation/documentation.cpp hello_world
+
+@end_toggle
+
+@add_toggle_java
+
+   Text for Java button
+   @snippet samples/java/tutorial_code/introduction/documentation/Documentation.java  hello_world
+
+@end_toggle
+
+@add_toggle_python
+
+   Text for Python button
+   @snippet samples/python/tutorial_code/introduction/documentation/documentation.py hello_world
+
+@end_toggle
+
+As you can see, the buttons are added automatically under the previous heading.
+
 ### Grouping commands {#tutorial_documentation_commands_group}
 
 All code entities should be put into named groups representing OpenCV modules and their internal
@@ -536,6 +613,8 @@ Write the tutorial {#tutorial_documentation_steps_tutorial}
 
     If you want to insert code blocks from this file into your tutorial, mark them with special doxygen comments (see [here](@ref tutorial_documentation_commands_include)).
 
+    If you want to write the tutorial in more than one programming language, use the toggle buttons for alternative comments and code (see [here](@ref tutorial_documentation_toggle_buttons_commands_include)).
+
 3.  Collect results  of the application work. It can be "before/after" images or some numbers
     representing performance or even a video.
 
@@ -552,22 +631,21 @@ Write the tutorial {#tutorial_documentation_steps_tutorial}
 
 5.  Modify your new page:
     -   Add page title and identifier, usually prefixed with <em>"tutorial_"</em> (see [here](@ref tutorial_documentation_md_page)).
+        You can add a link to the previous and next tutorial using the identifier
+        @verbatim
+@prev_tutorial{identifier}
+@next_tutorial{identifier}
+        @endverbatim
+        @warning Do **not** write the **hashtag (#)**, example: \n Incorrect: @verbatim @prev_tutorial{#tutorial_documentation} @endverbatim Correct: @verbatim @prev_tutorial{tutorial_documentation} @endverbatim
     -   Add brief description of your idea and tutorial goals.
     -   Describe your program and/or its interesting pieces.
     -   Describe your results, insert previously added images or other results.
 
-        To add a video use _htmlonly_, _endhtmlonly_ commands with raw html block inside:
+        To add a youtube video, e.g. www.youtube.com/watch?v= **ViPN810E0SU**, use _youtube_{**Video ID**}:
         @verbatim
-@htmlonly
-<div align="center">
-<iframe
-    title="my title" width="560" height="349"
-    src="http://www.youtube.com/embed/ViPN810E0SU?rel=0&loop=1"
-    frameborder="0" allowfullscreen align="middle">
-</iframe>
-</div>
-@endhtmlonly
+@youtube{ViPN810E0SU}
         @endverbatim
+
     -   Add bibliographic references if any (see [here](@ref tutorial_documentation_commands_cite)).
 
 6.  Add newly created tutorial to the corresponding table of contents. Just find
@@ -576,6 +654,8 @@ Write the tutorial {#tutorial_documentation_steps_tutorial}
     @verbatim
 -   @subpage tutorial_windows_visual_studio_image_watch
 
+    _Languages:_ C++, Java, Python
+
     _Compatibility:_ \>= OpenCV 2.4
 
     _Author:_ Wolf Kienzle
index 8eb9ca7..5493393 100644 (file)
@@ -50,11 +50,17 @@ int main( int argc, char* argv[])
     imshow( "Output", dst0 );
     waitKey();
 
+  //![kern]
     Mat kernel = (Mat_<char>(3,3) <<  0, -1,  0,
                                    -1,  5, -1,
                                     0, -1,  0);
+  //![kern]
+
     t = (double)getTickCount();
+
+  //![filter2D]
     filter2D( src, dst1, src.depth(), kernel );
+  //![filter2D]
     t = ((double)getTickCount() - t)/getTickFrequency();
     cout << "Built-in filter2D time passed in seconds:      " << t << endl;
 
@@ -63,13 +69,19 @@ int main( int argc, char* argv[])
     waitKey();
     return 0;
 }
+//! [basic_method]
 void Sharpen(const Mat& myImage,Mat& Result)
 {
+  //! [8_bit]
     CV_Assert(myImage.depth() == CV_8U);  // accept only uchar images
+  //! [8_bit]
 
+  //! [create_channels]
     const int nChannels = myImage.channels();
     Result.create(myImage.size(),myImage.type());
+  //! [create_channels]
 
+  //! [basic_method_loop]
     for(int j = 1 ; j < myImage.rows-1; ++j)
     {
         const uchar* previous = myImage.ptr<uchar>(j - 1);
@@ -84,9 +96,13 @@ void Sharpen(const Mat& myImage,Mat& Result)
                          -current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]);
         }
     }
+  //! [basic_method_loop]
 
+  //! [borders]
     Result.row(0).setTo(Scalar(0));
     Result.row(Result.rows-1).setTo(Scalar(0));
     Result.col(0).setTo(Scalar(0));
     Result.col(Result.cols-1).setTo(Scalar(0));
+  //! [borders]
 }
+//! [basic_method]
diff --git a/samples/cpp/tutorial_code/introduction/documentation/documentation.cpp b/samples/cpp/tutorial_code/introduction/documentation/documentation.cpp
new file mode 100644 (file)
index 0000000..23d8c02
--- /dev/null
@@ -0,0 +1,14 @@
+#include <iostream>
+
+/**
+ * @function main
+ * @brief Main function
+ */
+int main( void )
+{
+    //! [hello_world]
+    std::cout << "Hello World!";
+    //! [hello_world]
+
+    return 0;
+}
diff --git a/samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java b/samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java
new file mode 100644 (file)
index 0000000..804968e
--- /dev/null
@@ -0,0 +1,139 @@
+import org.opencv.core.*;
+import org.opencv.imgcodecs.Imgcodecs;
+import org.opencv.imgproc.Imgproc;
+
+import javax.swing.*;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+
+class MatMaskOperationsRun {
+
+    public void run() {
+
+    //! [laod_image]
+        Mat I = Imgcodecs.imread("../data/lena.jpg");
+        if(I.empty())
+            System.out.println("Error opening image");
+    //! [laod_image]
+
+        Image img = toBufferedImage( I );
+        displayImage("Input Image" , img, 0, 200 );
+
+        double t = System.currentTimeMillis();
+
+        Mat J = sharpen(I, new Mat());
+
+        t = ((double)System.currentTimeMillis() - t)/1000;
+        System.out.println("Hand written function times passed in seconds: " + t);
+
+        Image img2 = toBufferedImage( J );
+        displayImage("Output Image" , img2, 400, 400 );
+
+        Mat K = new Mat();
+    //![kern]
+        Mat kern = new Mat( 3, 3, CvType.CV_8S );
+        int row = 0, col = 0;
+        kern.put(row ,col, 0, -1, 0, -1, 5, -1, 0, -1, 0 );
+    //![kern]
+
+        System.out.println("kern = \n" + kern.dump());
+
+        t = System.currentTimeMillis();
+
+    //![filter2D]
+        Imgproc.filter2D(I, K, I.depth(), kern );
+    //![filter2D]
+
+        t = ((double)System.currentTimeMillis() - t)/1000;
+        System.out.println("Built-in filter2D time passed in seconds:      " + t);
+
+        Image img3 = toBufferedImage( J );
+        displayImage("filter2D Output Image" , img3, 800, 400 );
+    }
+
+    //! [basic_method]
+    public static double saturateCastUchar(double x) {
+        return x > 255.0 ? 255.0 : (x < 0.0 ? 0.0 : x);
+    }
+
+    public Mat sharpen(Mat myImage, Mat Result)
+    {
+      //! [8_bit]
+        myImage.convertTo(myImage, CvType.CV_8U);
+      //! [8_bit]
+
+      //! [create_channels]
+        int nChannels = myImage.channels();
+        Result.create(myImage.size(),myImage.type());
+      //! [create_channels]
+
+      //! [basic_method_loop]
+        for(int j = 1 ; j < myImage.rows()-1; ++j)
+        {
+            for(int i = 1 ; i < myImage.cols()-1; ++i)
+            {
+                double sum[] = new double[nChannels];
+
+                for(int k = 0; k < nChannels; ++k) {
+
+                    double top = -myImage.get(j - 1, i)[k];
+                    double bottom = -myImage.get(j + 1, i)[k];
+                    double center = (5 * myImage.get(j, i)[k]);
+                    double left = -myImage.get(j , i - 1)[k];
+                    double right = -myImage.get(j , i + 1)[k];
+
+                    sum[k] = saturateCastUchar(top + bottom + center + left + right);
+                }
+
+                Result.put(j, i, sum);
+            }
+        }
+      //! [basic_method_loop]
+
+      //! [borders]
+        Result.row(0).setTo(new Scalar(0));
+        Result.row(Result.rows()-1).setTo(new Scalar(0));
+        Result.col(0).setTo(new Scalar(0));
+        Result.col(Result.cols()-1).setTo(new Scalar(0));
+      //! [borders]
+
+        return Result;
+    }
+    //! [basic_method]
+
+    public Image toBufferedImage(Mat m) {
+        int type = BufferedImage.TYPE_BYTE_GRAY;
+        if ( m.channels() > 1 ) {
+            type = BufferedImage.TYPE_3BYTE_BGR;
+        }
+        int bufferSize = m.channels()*m.cols()*m.rows();
+        byte [] b = new byte[bufferSize];
+        m.get(0,0,b); // get all the pixels
+        BufferedImage image = new BufferedImage(m.cols(),m.rows(), type);
+        final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
+        System.arraycopy(b, 0, targetPixels, 0, b.length);
+        return image;
+    }
+
+    public void displayImage(String title, Image img, int x, int y)
+    {
+        ImageIcon icon=new ImageIcon(img);
+        JFrame frame=new JFrame(title);
+        JLabel lbl=new JLabel(icon);
+        frame.add(lbl);
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        frame.pack();
+        frame.setLocation(x, y);
+        frame.setVisible(true);
+    }
+}
+
+public class MatMaskOperations {
+    public static void main(String[] args) {
+
+        // Load the native library.
+        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+        new MatMaskOperationsRun().run();
+    }
+}
diff --git a/samples/java/tutorial_code/introduction/documentation/Documentation.java b/samples/java/tutorial_code/introduction/documentation/Documentation.java
new file mode 100644 (file)
index 0000000..f3f90a1
--- /dev/null
@@ -0,0 +1,9 @@
+public class Documentation {
+
+    public static void main (String[] args) {
+
+        //! [hello_world]
+        System.out.println ("Hello World!");
+        //! [hello_world]
+    }
+}
diff --git a/samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py b/samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py
new file mode 100644 (file)
index 0000000..82208fa
--- /dev/null
@@ -0,0 +1,57 @@
+import time
+import numpy as np
+import cv2
+## [basic_method]
+def sharpen(my_image):
+    my_image = cv2.cvtColor(my_image, cv2.CV_8U)
+
+    height, width, n_channels = my_image.shape
+    result = np.zeros(my_image.shape, my_image.dtype)
+
+    ## [basic_method_loop]
+    for j in range  (1, height-1):
+        for i in range  (1, width-1):
+            for k in range  (0, n_channels):
+                sum = 5 * my_image[j, i, k] - my_image[j + 1, i, k] - my_image[j - 1, i, k]\
+                     - my_image[j, i + 1, k] - my_image[j, i - 1, k];
+
+                if sum > 255:
+                    sum = 255
+                if sum < 0:
+                    sum = 0
+
+                result[j, i, k] = sum
+    ## [basic_method_loop]
+
+    return result
+## [basic_method]
+
+
+I = cv2.imread("../data/lena.jpg")
+cv2.imshow('Input Image', I)
+
+t = round(time.time())
+J = sharpen(I)
+t = (time.time() - t)/1000
+print "Hand written function times passed in seconds: %s" % t
+
+cv2.imshow('Output Image', J)
+
+t = time.time()
+## [kern]
+kernel = np.array([ [0,-1,0],
+                    [-1,5,-1],
+                    [0,-1,0] ],np.float32) # kernel should be floating point type
+## [kern]
+
+## [filter2D]
+K = cv2.filter2D(I, -1, kernel) # ddepth = -1, means destination image has depth same as input image.
+## [filter2D]
+
+t = (time.time() - t)/1000
+print "Built-in filter2D time passed in seconds:      %s" % t
+
+cv2.imshow('filter2D Output Image', K)
+
+cv2.waitKey(0)
+cv2.destroyAllWindows()
diff --git a/samples/python/tutorial_code/introduction/documentation/documentation.py b/samples/python/tutorial_code/introduction/documentation/documentation.py
new file mode 100644 (file)
index 0000000..bbd3e17
--- /dev/null
@@ -0,0 +1,5 @@
+print('Not showing this text because it is outside the snippet')
+
+## [hello_world]
+print('Hello world!')
+## [hello_world]