opencv边框处理copyMakeBorder
本文目的
目的:学习使用OpenCV函数设置边框(图像的额外填充)
语言:java
版本:opencv-410
简介:本程序的目的:
· 载入图片
· 让用户选择在输入图像中使用哪种填充。有5种选择:
1. 恒定值边框:对整个边框应用恒定值的填充。该值将每0.5秒随机更新一次。
2. 复制边框:将从原始图像边缘的像素值复制边框。
3.
· 用户通过按" c"(恒定)或" r"(复制),e,s,t选择任一选项
· 当用户按下" ESC"时程序结束
分解介绍
OpenCV函数
介绍函数:
core.copyMakeBorder(Mat src, Mat dst, int top, int bottom, int left, int right, int borderType, Scalar value)
参数:
1. src:源图像
2. dst:目标图像
3. top,bottom,left,right:图像每侧边框的长度(以像素为单位)。我们将它们定义为图像原始大小的5%。
4. borderType:定义要应用的边框类型。
5. value:如果borderType为BORDER_CONSTANT,这是用于填充边框像素的值。
边框类型有以下几种:
BORDER_CONSTANT = 0
常量法就是以一个常量像素值(由参数 value给定)填充扩充的边界值,这种方式在仿射变换,透视变换中非常常见
BORDER_REPLICATE = 1
复制法,也就是复制最边缘像素。比如下图,边框就是复制最边缘的区域的值
BORDER_REFLECT = 2
BORDER_REFLECT_101 = 4,
BORDER_REFLECT101 = BORDER_REFLECT_101,
BORDER_DEFAULT = BORDER_REFLECT_101,
对称法,也就是以最边缘像素为轴,对称复制。如下图,可以看到右侧的边框图就是对称复制相邻的像素值。这种方式也是OpenCV边界处理的默认方式(BORDER_DEFAULT=BORDER_REFLECT_101)
BORDER_WRAP = 3,
用另外一边堆成填充,如下图
BORDER_TRANSPARENT = 5,
试了下居然不支持。
代码
<code>package com.joe.vision.machine.vision.samples;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import java.io.FileNotFoundException;
import java.util.Random;
public class CopyMakeBorderDemo3 {
public void run(String[] args) throws FileNotFoundException {
// Declare the variables
Mat src, dst = new Mat();
int top, bottom, left, right;
int borderType = Core.BORDER_CONSTANT;
String window_name = "copyMakeBorder Demo";
String imageName = FileLoadUtils.getFilePath("static/time.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.exit(-1);
}
HighGui.namedWindow( window_name, HighGui.WINDOW_AUTOSIZE );
// Initialize arguments for the filter
top = (int) (0.05*src.rows()); bottom = top;
left = (int) (0.05*src.cols()); right = left;
//边框处理
copyMakeBorder(src, dst, top, bottom, left, right, borderType, window_name);
System.exit(0);
}
private void copyMakeBorder(Mat src, Mat dst, int top, int bottom, int left, int right, int borderType, String window_name) {
Random rng;
while( true ) {
rng = new Random();
Scalar value = new Scalar( rng.nextInt(256), rng.nextInt(256), rng.nextInt(256) );
Core.copyMakeBorder( src, dst, top, bottom, left, right, borderType, value);
HighGui.imshow( window_name, dst );
//接收用户输入,改变边框类型
UserInputBorderType userInputBorderType = new UserInputBorderType(borderType).invoke();
if (userInputBorderType.is()) break;
borderType = userInputBorderType.getBorderType();
}
}
public static void main(String[] args) throws FileNotFoundException {
// Load the native library.
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new CopyMakeBorderDemo3().run(args);
}
private class UserInputBorderType {
private boolean myResult;
private int borderType;
public UserInputBorderType(int borderType) {
this.borderType = borderType;
}
boolean is() {
return myResult;
}
public int getBorderType() {
return borderType;
}
public UserInputBorderType invoke() {
char c = (char) HighGui.waitKey(500);
c = Character.toLowerCase(c);
if( c == 27 ) {
myResult = true;
return this;
}
else if( c == 'c' ) {
borderType = Core.BORDER_CONSTANT;
}
else if( c == 'r' ) {
borderType = Core.BORDER_REPLICATE;
}else if(c == 's'){
borderType = Core.BORDER_REFLECT;
}else if(c == 't'){
borderType = Core.BORDER_WRAP;
}else if(c == 'e'){
borderType = Core.BORDER_ISOLATED;
}else if(c == 'f'){
borderType = Core.BORDER_TRANSPARENT;
}
myResult = false;
return this;
}
}
}
/<code>
閱讀更多 知秋一葉m 的文章