上一篇博客我们讲了如何在IDEA中使用OpenCV来进行一些简单的图像操作,这节我们来学习图像的一些基本的入门级操作。
先给大家贴个错误,如下图:
我们在使用awt处理图像的时候报了这个异常,HeadlessException 异常是在环境中不支持键盘、显示器或鼠标的环境中调用与键盘、显示器或鼠标有关的代码时,被抛出的异常。
网上有几种解决方法,比较方便的一种解决方法如下:
System.setProperty("java.awt.headless", "false");
这段代码激活了Headless模式,Headless模式是系统的一种配置模式。在该模式下,系统缺少了显示设备、键盘或鼠标。
这段代码相当于告诉程序,现在你要工作在Headless模式下,就不要指望硬件帮忙了,你得自力更生,依靠系统的计算能力模拟出这些特性来。
这里我们在Java中调用一下dll就行了,如下:
URL url = ClassLoader.getSystemResource("lib/opencv/opencv_java451.dll");//这里的dll根据你自己的实际情况写
System.load(url.getPath());
在OpenCV中我们可以使用imread()函数来进行图像的读取。图像的工作目录或图像的完整路径应给出。
该函数的定义如下:
static Mat imread(String filename)
static Mat imread(String filename, int flags)
flags是一个标志,它表示以何种方式来读取图像,它有常用的3个值,如下:
当然我们也可以在源码中查看其他的值,如下:
在OpenCV中我们可以使用imshow()函数来在窗口中显示图像,窗口自动适应图像的尺寸,该函数使用如下:
public static void imshow(String winname, Mat img);
第一个参数是窗口名称,它是一个字符串。第二个参数是我们读取图片的对象。
图像读取和显示的代码如下:
import org.junit.jupiter.api.Test;
import org.opencv.core.Mat;
import org.springframework.boot.test.context.SpringBootTest;
import java.net.URL;
import static org.opencv.highgui.HighGui.*;
import static org.opencv.imgcodecs.Imgcodecs.imread;
@SpringBootTest
class DemoApplicationTests {
@Test
public void testOpencv1() throws Exception {
// 解决awt报错问题
System.setProperty("java.awt.headless", "false");
// 加载动态库
URL url = ClassLoader.getSystemResource("lib/opencv/opencv_java451.dll");
System.load(url.getPath());
// 读取图像,以彩色模式(1)显示,0是灰度模式,-1是加载图像,包括alpha通道
Mat src = imread("D:\\OpenCV_Study\\demo1\\src\\main\\resources\\image\\test1.jpg",1);
if (src.empty()) {
throw new Exception("image is empty");
}
imshow("image",src);
waitKey(0);
destroyAllWindows();
}
}
读取彩色图像:
灰度模式读取图像:
加载图像,包括alpha通道:
上面的那段代码中有两个函数大家这里还需要讲一下:
public static void waitKey();
public static int waitKey(int delay);
从源码中我们可以看到waitKey()函数还有一个重载函数,其默认值为0,如下图:
所以我们写不写0都无所谓…吧
关于窗口
我们可以创建一个空窗口,然后再将图像加载到该窗口。在这种情况下,我们可以指定窗口是否可调整大小。这是通过函数namedWindow()来完成的。
该函数的定义:
public static void namedWindow(String winname);
public static void namedWindow(String winname, int flag);
flag默认情况下是WINDOW_AUTOSIZE,此时不能调整窗口的大小,但是,如果指定为WINDOW_NORMAL,则
可以调整窗口大小。
代码如下:
import org.junit.jupiter.api.Test;
import org.opencv.core.Mat;
import org.springframework.boot.test.context.SpringBootTest;
import java.net.URL;
import static org.opencv.highgui.HighGui.*;
import static org.opencv.imgcodecs.Imgcodecs.imread;
@SpringBootTest
class DemoApplicationTests {
@Test
public void testOpencv2() throws Exception{
System.setProperty("java.awt.headless","false");
URL url = ClassLoader.getSystemResource("lib/opencv/opencv_java451.dll");
System.load(url.getPath());
Mat image = imread("D:\\OpenCV_Study\\demo1\\src\\main\\resources\\image\\test1.jpg",1);
if (image.empty()){
throw new Exception("image is empty");
}
//这里我们创建了两个窗口,一个叫imag1,一个叫imag2,他们分别是可以调整窗口大小和不可以调整窗口大小
namedWindow("imag1",WINDOW_NORMAL); //可以调整窗口大小
namedWindow("imag2",WINDOW_AUTOSIZE); //不可以调整窗口大小
//将图像加载进窗口,分别显示这两个窗口
imshow("imag1",image);
imshow("imag2",image);
waitKey();
destroyAllWindows();
}
}
我们可以使用函数imwrite()来保存图像,该函数定义如下:
public static boolean imwrite(String filename, Mat img);
第一个参数是文件名(得包含文件路径),第二个参数是要保存的图像。
代码示例如下:
import org.junit.jupiter.api.Test;
import org.opencv.core.Mat;
import org.springframework.boot.test.context.SpringBootTest;
import java.net.URL;
import static org.opencv.highgui.HighGui.*;
import static org.opencv.imgcodecs.Imgcodecs.imread;
import static org.opencv.imgcodecs.Imgcodecs.imwrite;
@SpringBootTest
class DemoApplicationTests {
@Test
public void testOpencv3() throws Exception{
System.setProperty("java.awt.headless","false");
URL url = ClassLoader.getSystemResource("lib/opencv/opencv_java451.dll");
System.load(url.getPath());
Mat image = imread("D:\\OpenCV_Study\\demo1\\src\\main\\resources\\image\\test1.jpg",0);
if (image.empty()){
throw new Exception("image is empty");
}
imshow("image",image);
//此处设置为检测特定的按键
int flag = waitKey(0);
if (flag==27){
destroyAllWindows();
}else if (flag==83){
imwrite("D:\\OpenCV_Study\\demo1\\src\\main\\resources\\image\\test2.jpg",image);
destroyAllWindows();
}
}
}
上面这段代码中我们将结束事件设置为检测特定的按键,即按了Esc键(值为23)就直接销毁窗口退出程序,按了"s"键(值为83)就保存灰度模式的图片。
结果:
可以看到,我们在键盘上按了"s"之后灰度模式的图像就被保存到相对应路径下了。