Adding borders to your images {#tutorial_copyMakeBorder}
=============================
+@prev_tutorial{tutorial_filter_2d}
+@next_tutorial{tutorial_sobel_derivatives}
+
Goal
----
In this tutorial you will learn how to:
-- Use the OpenCV function @ref cv::copyMakeBorder to set the borders (extra padding to your
+- Use the OpenCV function **copyMakeBorder()** to set the borders (extra padding to your
image).
Theory
This will be seen more clearly in the Code section.
-Code
-----
-
--# **What does this program do?**
+- **What does this program do?**
- Load an image
- Let the user choose what kind of padding use in the input image. There are two options:
The user chooses either option by pressing 'c' (constant) or 'r' (replicate)
- The program finishes when the user presses 'ESC'
--# The tutorial code's is shown lines below. You can also download it from
- [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp)
- @include samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp
+Code
+----
+
+The tutorial code's is shown lines below.
+
+@add_toggle_cpp
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp)
+@include samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp
+@end_toggle
+
+@add_toggle_java
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/ImgTrans/MakeBorder/CopyMakeBorder.java)
+@include samples/java/tutorial_code/ImgTrans/MakeBorder/CopyMakeBorder.java
+@end_toggle
+
+@add_toggle_python
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py)
+@include samples/python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py
+@end_toggle
Explanation
-----------
--# First we declare the variables we are going to use:
- @snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp variables
+#### Declare the variables
+
+First we declare the variables we are going to use:
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp variables
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/MakeBorder/CopyMakeBorder.java variables
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py variables
+@end_toggle
+
+Especial attention deserves the variable *rng* which is a random number generator. We use it to
+generate the random border color, as we will see soon.
+
+#### Load an image
+
+As usual we load our source image *src*:
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp load
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/MakeBorder/CopyMakeBorder.java load
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py load
+@end_toggle
+
+#### Create a window
+
+After giving a short intro of how to use the program, we create a window:
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp create_window
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/MakeBorder/CopyMakeBorder.java create_window
+@end_toggle
- Especial attention deserves the variable *rng* which is a random number generator. We use it to
- generate the random border color, as we will see soon.
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py create_window
+@end_toggle
--# As usual we load our source image *src*:
- @snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp load
+#### Initialize arguments
--# After giving a short intro of how to use the program, we create a window:
- @snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp create_window
--# Now we initialize the argument that defines the size of the borders (*top*, *bottom*, *left* and
- *right*). We give them a value of 5% the size of *src*.
- @snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp init_arguments
--# The program runs in a **for** loop. If the user presses 'c' or 'r', the *borderType* variable
- takes the value of *BORDER_CONSTANT* or *BORDER_REPLICATE* respectively:
- @snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp check_keypress
--# In each iteration (after 0.5 seconds), the variable *value* is updated...
- @snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp update_value
- with a random value generated by the **RNG** variable *rng*. This value is a number picked
- randomly in the range \f$[0,255]\f$
+Now we initialize the argument that defines the size of the borders (*top*, *bottom*, *left* and
+*right*). We give them a value of 5% the size of *src*.
--# Finally, we call the function @ref cv::copyMakeBorder to apply the respective padding:
- @snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp copymakeborder
- The arguments are:
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp init_arguments
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/MakeBorder/CopyMakeBorder.java init_arguments
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py init_arguments
+@end_toggle
+
+#### Loop
+
+The program runs in an infinite loop while the key **ESC** isn't pressed.
+If the user presses '**c**' or '**r**', the *borderType* variable
+takes the value of *BORDER_CONSTANT* or *BORDER_REPLICATE* respectively:
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp check_keypress
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/MakeBorder/CopyMakeBorder.java check_keypress
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py check_keypress
+@end_toggle
+
+#### Random color
+
+In each iteration (after 0.5 seconds), the random border color (*value*) is updated...
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp update_value
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/MakeBorder/CopyMakeBorder.java update_value
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py update_value
+@end_toggle
+
+This value is a set of three numbers picked randomly in the range \f$[0,255]\f$.
+
+#### Form a border around the image
+
+Finally, we call the function **copyMakeBorder()** to apply the respective padding:
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp copymakeborder
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/MakeBorder/CopyMakeBorder.java copymakeborder
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py copymakeborder
+@end_toggle
+
+- The arguments are:
-# *src*: Source image
-# *dst*: Destination image
-# *value*: If *borderType* is *BORDER_CONSTANT*, this is the value used to fill the border
pixels.
--# We display our output image in the image created previously
- @snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp display
+#### Display the results
+
+We display our output image in the image created previously
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp display
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/MakeBorder/CopyMakeBorder.java display
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py display
+@end_toggle
Results
-------
- @subpage tutorial_copyMakeBorder
+ *Languages:* C++, Java, Python
+
*Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán
using namespace cv;
//![variables]
+// Declare the variables
Mat src, dst;
int top, bottom, left, right;
-int borderType;
+int borderType = BORDER_CONSTANT;
const char* window_name = "copyMakeBorder Demo";
RNG rng(12345);
//![variables]
*/
int main( int argc, char** argv )
{
- //![load]
- String imageName("../data/lena.jpg"); // by default
- if (argc > 1)
- {
- imageName = argv[1];
- }
- src = imread( imageName, IMREAD_COLOR ); // Load an image
+ //![load]
+ const char* imageName = argc >=2 ? argv[1] : "../data/lena.jpg";
- if( src.empty() )
- {
- printf(" No data entered, please enter the path to an image file \n");
- return -1;
- }
- //![load]
+ // Loads an image
+ src = imread( imageName, IMREAD_COLOR ); // Load an image
- /// Brief how-to for this program
- printf( "\n \t copyMakeBorder Demo: \n" );
- printf( "\t -------------------- \n" );
- printf( " ** Press 'c' to set the border to a random constant value \n");
- printf( " ** Press 'r' to set the border to be replicated \n");
- printf( " ** Press 'ESC' to exit the program \n");
+ // Check if image is loaded fine
+ if( src.empty()) {
+ printf(" Error opening image\n");
+ printf(" Program Arguments: [image_name -- default ../data/lena.jpg] \n");
+ return -1;
+ }
+ //![load]
- //![create_window]
- namedWindow( window_name, WINDOW_AUTOSIZE );
- //![create_window]
+ // Brief how-to for this program
+ printf( "\n \t copyMakeBorder Demo: \n" );
+ printf( "\t -------------------- \n" );
+ printf( " ** Press 'c' to set the border to a random constant value \n");
+ printf( " ** Press 'r' to set the border to be replicated \n");
+ printf( " ** Press 'ESC' to exit the program \n");
- //![init_arguments]
- /// Initialize arguments for the filter
- top = (int) (0.05*src.rows); bottom = (int) (0.05*src.rows);
- left = (int) (0.05*src.cols); right = (int) (0.05*src.cols);
- //![init_arguments]
+ //![create_window]
+ namedWindow( window_name, WINDOW_AUTOSIZE );
+ //![create_window]
- dst = src;
- imshow( window_name, dst );
+ //![init_arguments]
+ // Initialize arguments for the filter
+ top = (int) (0.05*src.rows); bottom = top;
+ left = (int) (0.05*src.cols); right = left;
+ //![init_arguments]
- for(;;)
- {
- //![check_keypress]
- char c = (char)waitKey(500);
- if( c == 27 )
- { break; }
- else if( c == 'c' )
- { borderType = BORDER_CONSTANT; }
- else if( c == 'r' )
- { borderType = BORDER_REPLICATE; }
- //![check_keypress]
+ for(;;)
+ {
+ //![update_value]
+ Scalar value( rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255) );
+ //![update_value]
- //![update_value]
- Scalar value( rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255) );
- //![update_value]
+ //![copymakeborder]
+ copyMakeBorder( src, dst, top, bottom, left, right, borderType, value );
+ //![copymakeborder]
- //![copymakeborder]
- copyMakeBorder( src, dst, top, bottom, left, right, borderType, value );
- //![copymakeborder]
+ //![display]
+ imshow( window_name, dst );
+ //![display]
- //![display]
- imshow( window_name, dst );
- //![display]
- }
+ //![check_keypress]
+ char c = (char)waitKey(500);
+ if( c == 27 )
+ { break; }
+ else if( c == 'c' )
+ { borderType = BORDER_CONSTANT; }
+ else if( c == 'r' )
+ { borderType = BORDER_REPLICATE; }
+ //![check_keypress]
+ }
- return 0;
+ return 0;
}
--- /dev/null
+/**
+ * @file CopyMakeBorder.java
+ * @brief Sample code that shows the functionality of copyMakeBorder
+ */
+
+import org.opencv.core.*;
+import org.opencv.highgui.HighGui;
+import org.opencv.imgcodecs.Imgcodecs;
+
+import java.util.Random;
+
+class CopyMakeBorderRun {
+
+ public void run(String[] args) {
+
+ //! [variables]
+ // Declare the variables
+ Mat src, dst = new Mat();
+ int top, bottom, left, right;
+ int borderType = Core.BORDER_CONSTANT;
+ String window_name = "copyMakeBorder Demo";
+ Random rng;
+ //! [variables]
+
+ //! [load]
+ String imageName = ((args.length > 0) ? args[0] : "../data/lena.jpg");
+
+ // Load an image
+ src = Imgcodecs.imread(imageName, Imgcodecs.IMREAD_COLOR);
+
+ // Check if image is loaded fine
+ if( src.empty() ) {
+ System.out.println("Error opening image!");
+ System.out.println("Program Arguments: [image_name -- default ../data/lena.jpg] \n");
+ System.exit(-1);
+ }
+ //! [load]
+
+ // Brief how-to for this program
+ System.out.println("\n" +
+ "\t copyMakeBorder Demo: \n" +
+ "\t -------------------- \n" +
+ " ** Press 'c' to set the border to a random constant value \n" +
+ " ** Press 'r' to set the border to be replicated \n" +
+ " ** Press 'ESC' to exit the program \n");
+
+ //![create_window]
+ HighGui.namedWindow( window_name, HighGui.WINDOW_AUTOSIZE );
+ //![create_window]
+
+ //! [init_arguments]
+ // Initialize arguments for the filter
+ top = (int) (0.05*src.rows()); bottom = top;
+ left = (int) (0.05*src.cols()); right = left;
+ //! [init_arguments]
+
+ while( true ) {
+ //! [update_value]
+ rng = new Random();
+ Scalar value = new Scalar( rng.nextInt(256),
+ rng.nextInt(256), rng.nextInt(256) );
+ //! [update_value]
+
+ //! [copymakeborder]
+ Core.copyMakeBorder( src, dst, top, bottom, left, right, borderType, value);
+ //! [copymakeborder]
+ //! [display]
+ HighGui.imshow( window_name, dst );
+ //! [display]
+
+ //![check_keypress]
+ char c = (char) HighGui.waitKey(500);
+ c = Character.toLowerCase(c);
+
+ if( c == 27 )
+ { break; }
+ else if( c == 'c' )
+ { borderType = Core.BORDER_CONSTANT;}
+ else if( c == 'r' )
+ { borderType = Core.BORDER_REPLICATE;}
+ //![check_keypress]
+ }
+
+ System.exit(0);
+ }
+}
+
+public class CopyMakeBorder {
+ public static void main(String[] args) {
+ // Load the native library.
+ System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+ new CopyMakeBorderRun().run(args);
+ }
+}
--- /dev/null
+"""
+@file copy_make_border.py
+@brief Sample code that shows the functionality of copyMakeBorder
+"""
+import sys
+from random import randint
+import cv2
+
+
+def main(argv):
+ ## [variables]
+ # First we declare the variables we are going to use
+ borderType = cv2.BORDER_CONSTANT
+ window_name = "copyMakeBorder Demo"
+ ## [variables]
+ ## [load]
+ imageName = argv[0] if len(argv) > 0 else "../data/lena.jpg"
+
+ # Loads an image
+ src = cv2.imread(imageName, cv2.IMREAD_COLOR)
+
+ # Check if image is loaded fine
+ if src is None:
+ print ('Error opening image!')
+ print ('Usage: copy_make_border.py [image_name -- default ../data/lena.jpg] \n')
+ return -1
+ ## [load]
+ # Brief how-to for this program
+ print ('\n'
+ '\t copyMakeBorder Demo: \n'
+ ' -------------------- \n'
+ ' ** Press \'c\' to set the border to a random constant value \n'
+ ' ** Press \'r\' to set the border to be replicated \n'
+ ' ** Press \'ESC\' to exit the program ')
+ ## [create_window]
+ cv2.namedWindow(window_name, cv2.WINDOW_AUTOSIZE)
+ ## [create_window]
+ ## [init_arguments]
+ # Initialize arguments for the filter
+ top = int(0.05 * src.shape[0]) # shape[0] = rows
+ bottom = top
+ left = int(0.05 * src.shape[1]) # shape[1] = cols
+ right = left
+ ## [init_arguments]
+ while 1:
+ ## [update_value]
+ value = [randint(0, 255), randint(0, 255), randint(0, 255)]
+ ## [update_value]
+ ## [copymakeborder]
+ dst = cv2.copyMakeBorder(src, top, bottom, left, right, borderType, None, value)
+ ## [copymakeborder]
+ ## [display]
+ cv2.imshow(window_name, dst)
+ ## [display]
+ ## [check_keypress]
+ c = cv2.waitKey(500)
+
+ if c == 27:
+ break
+ elif c == 99: # 99 = ord('c')
+ borderType = cv2.BORDER_CONSTANT
+ elif c == 114: # 114 = ord('r')
+ borderType = cv2.BORDER_REPLICATE
+ ## [check_keypress]
+ return 0
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])