mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 09:25:45 +08:00
Tutorial Make Border
This commit is contained in:
parent
a6f5e1f0ca
commit
9ff33dacfc
@ -1,12 +1,15 @@
|
||||
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
|
||||
@ -30,10 +33,7 @@ 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:
|
||||
|
||||
@ -45,38 +45,153 @@ Code
|
||||
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
|
||||
|
||||
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.
|
||||
First we declare the variables we are going to use:
|
||||
|
||||
-# As usual we load our source image *src*:
|
||||
@snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp load
|
||||
@add_toggle_cpp
|
||||
@snippet cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp variables
|
||||
@end_toggle
|
||||
|
||||
-# 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$
|
||||
@add_toggle_java
|
||||
@snippet java/tutorial_code/ImgTrans/MakeBorder/CopyMakeBorder.java variables
|
||||
@end_toggle
|
||||
|
||||
-# 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_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
|
||||
|
||||
@add_toggle_python
|
||||
@snippet python/tutorial_code/ImgTrans/MakeBorder/copy_make_border.py create_window
|
||||
@end_toggle
|
||||
|
||||
#### Initialize arguments
|
||||
|
||||
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*.
|
||||
|
||||
@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
|
||||
@ -87,8 +202,21 @@ Explanation
|
||||
-# *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
|
||||
-------
|
||||
|
@ -87,6 +87,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_copyMakeBorder
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
|
@ -11,9 +11,10 @@
|
||||
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]
|
||||
@ -24,21 +25,20 @@ RNG rng(12345);
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
//![load]
|
||||
String imageName("../data/lena.jpg"); // by default
|
||||
if (argc > 1)
|
||||
{
|
||||
imageName = argv[1];
|
||||
}
|
||||
const char* imageName = argc >=2 ? argv[1] : "../data/lena.jpg";
|
||||
|
||||
// Loads an image
|
||||
src = imread( imageName, IMREAD_COLOR ); // Load an image
|
||||
|
||||
if( src.empty() )
|
||||
{
|
||||
printf(" No data entered, please enter the path to an image file \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]
|
||||
|
||||
/// Brief how-to for this program
|
||||
// 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");
|
||||
@ -50,26 +50,13 @@ int main( int argc, char** argv )
|
||||
//![create_window]
|
||||
|
||||
//![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);
|
||||
// Initialize arguments for the filter
|
||||
top = (int) (0.05*src.rows); bottom = top;
|
||||
left = (int) (0.05*src.cols); right = left;
|
||||
//![init_arguments]
|
||||
|
||||
dst = src;
|
||||
imshow( window_name, dst );
|
||||
|
||||
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]
|
||||
|
||||
//![update_value]
|
||||
Scalar value( rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255) );
|
||||
//![update_value]
|
||||
@ -81,6 +68,16 @@ int main( int argc, char** argv )
|
||||
//![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;
|
||||
|
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
"""
|
||||
@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:])
|
Loading…
Reference in New Issue
Block a user