日志

JavaCV与OpenCV的区别和使用中遇到的问题

 来源    2020-09-16    0  

  写这篇随笔的原因是因为我用了JavaCV一段时间后项目情况糟透了,可能大家很熟悉OpenCV,也有一部分人熟悉JavaCV,但是我相信真正把JavaCV用到生产上的不是太多。

我参与图片处理项目快一个月了,最初抱着很大兴趣参与这个项目,渐渐的发现这个领域并不太好走。

  • 官网地址

JavaCV:http://bytedeco.org/,https://github.com/bytedeco/javacv

OpenCV:https://docs.opencv.org

  JavaCV据说比OpenCV多封装了很多库,但是目前我都没用到,当时应用JavaCV的理由是不用单独安装OpenCV,不用根据环境进行库的切换,

引入pom文件后则可以直接干活。

<dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5.4</version>
        </dependency>
  • JavaCV的不稳定问题

多次仿射结果不一致,我想用JavaCV做仿射变换,缩小图片,发现多次结果不一致,但是用OpenCV就没有这个问题

@Test
    public void warpAffine() {
        Mat src=imread("D:\\img\\0_7p-1.jpg");
        Mat dst = new Mat();
        Point2f point2fSrc = new Point2f(3);

        point2fSrc.position(0).y(0).x(0);//TopLeft
        point2fSrc.position(1).y(0).x(src.cols()-1);//TopRight
        point2fSrc.position(2).y(src.rows()-1).x(0);//Bottom Left


        Point2f point2fDst = new Point2f(3);
        point2fDst.position(0).y(0).x(0);//TopLeft
        point2fDst.position(1).y(0).x(src.cols()/2);//TopRight
        point2fDst.position(2).y(src.rows()/2).x(0);//Bottom Left
 
        Date date=new Date();
        Mat affineTrans2 = opencv_imgproc.getAffineTransform(point2fSrc,point2fDst);
        opencv_imgproc.warpAffine(src, dst, affineTrans2, src.size());
        System.out.println(new Date().getTime()-date.getTime());
        imwrite("D:\\img\\7p-2.jpg", dst);

    }

结果应为等比缩小一倍,但是右边的图有变形,而且多次结果会不一致。

再看直接用OpenCV javaAPI的结果

@Test
    public void test(){

        System.load("C:\\Program Files\\opencv\\opencv\\build\\java\\x64\\opencv_java410.dll");

        System.out.println("Welcome to OpenCV " + Core.VERSION);

        Mat src = Imgcodecs.imread("D:/img/0_7p-1.jpg");
        Mat dst = new Mat((src.rows()/2),src.cols()/2,src.type());

        Point p1 = new Point( 0,0 );
        Point p2 = new Point( src.cols() - 1, 0 );
        Point p3 = new Point( 0, src.rows() - 1 );

        Point p4 = new Point( 0, 0);
        Point p5 = new Point( src.cols() /2, 0 );
        Point p6 = new Point( 0, src.rows() /2);

//        Point p4 = new Point( src.cols() /2, 0);
//        Point p5 = new Point( src.cols() /2, src.rows() /2 );
//       Point p6 = new Point( 0, 0);

        MatOfPoint2f ma1 = new MatOfPoint2f(p1,p2,p3);
        MatOfPoint2f ma2 = new MatOfPoint2f(p4,p5,p6);
Date date=new Date();
        // Creating the transformation matrix
        Mat tranformMatrix = Imgproc.getAffineTransform(ma1,ma2);



        // Applying Wrap Affine
        Imgproc.warpAffine(src, dst, tranformMatrix, src.size());
        System.out.println(new Date().getTime()-date.getTime());

        // Writing the image
        Imgcodecs.imwrite("D:/img/bbb.jpg", dst);
    }

bbb.jpg图像处理正确,多次执行代码结果一致。

  • 性能对比:

同样的图片放射缩小,基于JavaCV处理时间为174毫秒,OpenCV javaAPI的处理时间为11毫秒,差别接近17倍;

这里我要说明一下,例子不具备普遍性,其它API我没有一个一个的测试,希望对大家有帮助。

  • JavaCV的另外一个多线程并发问题:

我尝试用20个线程压测系统报了一个JVM错误:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffec4062738, pid=21668, tid=8404
#
# JRE version: Java(TM) SE Runtime Environment 18.9 (11.0.8+10) (build 11.0.8+10-LTS)
# Java VM: Java HotSpot(TM) 64-Bit Server VM 18.9 (11.0.8+10-LTS, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C  [opencv_imgproc430.dll+0x1e2738]
#
# Core dump will be written. Default location: E:\img\hs_err_pid21668.mdmp
#
# If you would like to submit a bug report, please visit:
#   https://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

查看mdmp文件:

转储文件:    hs_err_pid21668.mdmp : E:\img\hs_err_pid21668.mdmp
上次写入时间:    2020/9/16 10:04:42
进程名称:    java.exe : C:\Program Files\Java\jdk-11.0.8\bin\java.exe
进程架构:    x64
异常代码:    0xC0000005
异常信息:    该线程尝试读写某个虚拟地址,而它对该地址不具有相应的访问权限。
堆信息:    存在

查询一番资料并没有找到解决办法,我并不清楚直接用OpenCV JavaAPI是否有同样的问题,如果知道如何解决欢迎留言,感激不尽。

虽然找到了一个缓解问题的方法,是设置JVM参数的-Xmx8g -Xms8g -Xmn4g,20个线程测试一般不出问题,50个并发有一半的概率死掉。

现在我决定用OpenCV重写项目,但愿不会再出现这个问题。

在JavaCV或OPENCV中查找轮廓
问答我有问题,但我不知道是什么!我有下一个代码,当我调试它时,调试器停止在 IplImage iplGray = cvCreateImage(cvGetSize(iplUltima), 8, 1 ); C ...
1
如何在javacv或opencv中开始图像处理之前提高图像质量?
问答我有一个400×400图像的图像,以识别它的不同组件.但是当我尝试使用大部分时间识别组件时,它无法提供正确的答案.所以我需要知道javacv或opencv中是否有某种方法可以提高图像质量或增加图像大小 ...
1
OpenCV(JavaCV)vs OpenCV(C/C++接口)
问答我只是想知道,与使用JavaCV相比,OpenCV的C/C++实现相对于给定的一组机器相对来说是否具有显着的速度性能优势. 如果我错了,请更正我,但我的理解是,opencv的c / c实现更接近于机器 ...
1
我应该在Android上使用JavaCV或OpenCV的java库吗?
问答http://opencv.willowgarage.com/wiki/Android还是http://code.google.com/p/javacv/? 我是计算机视觉的新手,想要在手机相机上做一 ...
1
java – OpenCV和OpenCL之间的区别
问答任何人都可以解释一下OpenCV和OpenCL之间有什么区别?什么适合Java中的Android图像处理?::OpenCL是大规模并行处理的标准,它可以帮助图像处理,但它的级别非常低,旨在简化利用许多 ...
1
git – 通过使用预构建的库和从源文件创建自己的库来安装OpenCV有什么区别?
问答我需要知道安装OpenCV之间的区别 1.使用预建库? 2.通过源文件创建自己的库? 当我们做第一个时,我们只需要下载OpenCV新版本并将其解压缩,然后使用CMake使用Visual Studio进 ...
1
simpleCV和openCV之间的区别
问答我不知道要使用哪一个.哪个是最好的?还是,他们都是一样的? 在一些文章中,我读到simpleCV是一种允许您访问openCV的界面.我不明白这一点.那我们为什么要单独安装openCV?::OpenCV ...
2
opencv – cvMat,Mat和IpImage之间的区别
问答目前我正在试图发现opencv库,但是看起来这些数据结构有点混乱.所以有cv :: Mat,cvMat和IpImage,以及各种不同的例子. 我明白,从C到C已经有一个opencv的迁移,然后对2.4 ...
1
opencv python中cv2.NORM_L2和cv2.NORM_L1之间的区别
问答我正在使用python额外模块的sift算法进行一些功能匹配. 虽然我不明白的一件事是传递给BFMatcher的normType背后的概念.即在哪种情况下必须使用哪些? 任何帮助都是无价的::来自Wo ...
1
如何使用opencv / javacv识别图像中的U形?
问答目前我正在开发javacv上的图像处理项目.在那里我必须识别特定多边形内的U形. 这是两种类型的图像,我必须识别图像中的图像是否具有两个U形或单个U形.我经历了很多教程,但我无法找到适当的指导方针来澄 ...
2
opencv – Mat :: clone和Mat :: copyTo之间有什么区别?
问答我知道"copyTo"可以处理掩码.但是当不需要掩码时,我可以同时使用吗? http://docs.opencv.org/modules/core/doc/basic_struct ...
1
OpenCV Mat类型的区别
问答OpenCV cv :: Mat类型有什么区别? 更具体来说,CV_64F和CV_64FC1或CV_64FC2有什么区别?当我创建一个具有双重值的cv :: Mat对象时,应该使用哪一个?::Cx部分 ...
1
在OpenCV中,UMat和Mat有什么区别?
问答我已经通过文档,没有得到关于UMat的清楚的详细描述;但是我认为它与GPU和CPU有关.请帮我出来 谢谢.::也许本文件的第3部分将有助于: https://software.intel.com/si ...
1
图像处理 – 如何使用javacv / opencv识别黑色多边形上的点?
问答我试图识别这个黑色多边形周围的轮廓,我需要访问这些点,但它不适合我.这是输入图像 但是,当我尝试执行以下代码时,它没有给出预期的结果,这意味着它应该. CanvasFrame cnvs=new Can ...
OPENCV中的cvtype值有什么区别?
问答我尝试了很多常量值,但是我找不到cvtype值之间的区别. 它是干什么用的? 我尝试过像CV_8UC4和CV_16S这样的值. 我没有在参考资料中找到这些信息.::类型的命名主体是CV_ {U | S ...
1
OpenCV中的相位相关和模板匹配有什么区别?
问答我最近在OpenCV中发现了相位相关,使用Log Polar Transform(LPT)可以执行旋转和缩放不变模板匹配.我想知道这个方法和这里描述的所有模板匹配方法之间有什么区别,这些方法对于任何旋 ...
1
OpenCV/JavaCV面部识别 – 非常相似的置信度值
问答我将解释我正在努力做什么,因为它似乎是相关的,以了解我的问题. 我目前正在根据数据库中已知的图片来尝试对相机前面的人进行脸部识别. 这些已知的照片正在从识别智能卡(其仅包含单个正面脸部照片)或来自社交 ...
JavaCV / OpenCV:cvLoadImage无法正常工作
问答我安装了JavaCV / OpenCV库,我遇到了基本示例代码的问题. 根据我看过的几个例子,这段代码应该加载一个图像: IplImage image = cvLoadImage("C:\\ ...
如何使用opencv或javacv识别多边形?
问答我正在做一个使用图像处理技术来识别不同对象及其长度的项目.我在javaCV以及OpenCV中经历了很多例子.但不幸的是我无法识别多边形的T形. 我尝试使用以下矩形识别方法,但我失败了. public ...
1
图像过滤/操作在Android中使用JavaCv(OpenCV的Java包装器)
问答我的目标是将过滤器(灰度,复古,对比度,锐化,模糊,平滑等)应用于JavaCv的iplImage.在这样做时,我遇到了这些函数/类:iplImage,CvMat,cvInRangeS,cvCvtCol ...
1