OpenCV 相机预览中未显示蒙版

2023-12-27

我想制作一个简单的 Android 应用程序,它在使用 OpenCV 检测到的面部上放置面具,如下例所示:

人脸面具检测教程 http://opencvexamples.blogspot.com/2013/11/putting-mask-on-face-using-opencv.html

我将 C++ 翻译成 Java 来用于我的应用程序。遮罩的大小得到了很好的调整,白色部分被消除了(我在预览中的 ImageView 中显示了测试结果),但遮罩从未出现在绿色矩形中检测到的脸上:

结果截图 https://i.stack.imgur.com/rDRH6.jpg

我的代码:

    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
             [...]

    for( int i = 0; i < facesArray.length; i++)
        min_face_size = facesArray[0].width*0.7;
        max_face_size = facesArray[0].width*1.5;
        Point center=new Point (facesArray[i].x + facesArray[i].width/2, facesArray[i].y + facesArray[i].height/2);
        mRgba=putMask(mRgba,center, new Size(facesArray[i].width, facesArray[i].height));
    }
    return mRgba;
}

Mat putMask(Mat src, Point center, Size face_size)
{

    //mask : loaded mask image
    Mat mask1 = new Mat(); //resized mask
    src1 = new Mat(); //ROI
    m = new Mat();

    Imgproc.resize(mask ,mask1,face_size);

    // ROI selection
    roi = new Rect((int) (center.x - face_size.width/2), (int) (center.y - face_size.height/2),(int) face_size.width, (int) face_size.height);
    //Rect roi = new Rect(100, 100, (int) face_size.width, (int) face_size.height);
    src.submat(roi).copyTo(src1);


    // to make the white region transparent
    Mat mask2 = new Mat(); //greymask
    m1= new Mat();
    Imgproc.cvtColor(mask1,mask2, Imgproc.COLOR_BGR2GRAY);
    Imgproc.threshold(mask2,mask2,230,255, Imgproc.THRESH_BINARY_INV);

    ArrayList<Mat> maskChannels = new ArrayList<>(3);
    ArrayList<Mat> result_mask = new ArrayList<>(3);
    result_mask.add(new Mat());
    result_mask.add(new Mat());
    result_mask.add(new Mat());

    Core.split(mask1, maskChannels);

    Log.e(TAG, "MASK maskChannels :"+maskChannels.get(0).size());
    Log.e(TAG, "MASK mask2 :"+mask2.size());

    Core.bitwise_and(maskChannels.get(0),mask2, result_mask.get(0));
    Core.bitwise_and(maskChannels.get(1),mask2, result_mask.get(1));
    Core.bitwise_and(maskChannels.get(2),mask2, result_mask.get(2));
    Core.merge(result_mask, m);        


    Core.subtract(mask2, new Scalar(255), mask2);

    ArrayList<Mat> srcChannels = new ArrayList<>(3);
    Core.split(src1, srcChannels);
    Core.bitwise_and(srcChannels.get(0),mask2, result_mask.get(0));
    Core.bitwise_and(srcChannels.get(1),mask2, result_mask.get(1));
    Core.bitwise_and(srcChannels.get(2),mask2, result_mask.get(2));
    Core.merge(result_mask,m1);        


    Core.addWeighted(m,1,m1,1,0,m1);    

    m1.copyTo(src.submat(roi));

    return src;
}

=============

感谢@hariprasad :)这里是工作代码:

 onCreate(){
          [...]
                try {
                    File file = new File(Environment.getExternalStorageDirectory(), "1-alpha.png");

                    mask = Imgcodecs.imread(file.getPath(), -1);

                }catch (Exception e){
                    e.printStackTrace();
                }
        }


Mat putMask(Mat src, Point center, Size face_size)
{

    //mask : masque chargé depuis l'image
    Mat mask_resized = new Mat(); //masque resizé
    src_roi = new Mat(); //ROI du visage croppé depuis la preview
    roi_gray = new Mat();


    Imgproc.resize(mask ,mask_resized,face_size);

    // ROI selection
    roi = new Rect((int) (center.x - face_size.width/2), (int) (center.y - face_size.height/2),(int) face_size.width, (int) face_size.height);
    //Rect roi = new Rect(10, 10, (int) face_size.width, (int) face_size.height);

    src.submat(roi).copyTo(src_roi);

    Log.e(TAG, "MASK SRC1 :"+ src_roi.size());

    // to make the white region transparent
    Mat mask_grey = new Mat(); //greymask
    roi_rgb = new Mat();
    Imgproc.cvtColor(mask_resized,mask_grey, Imgproc.COLOR_BGRA2GRAY);
    Imgproc.threshold(mask_grey,mask_grey,230,255, Imgproc.THRESH_BINARY_INV);

    ArrayList<Mat> maskChannels = new ArrayList<>(4);
    ArrayList<Mat> result_mask = new ArrayList<>(4);
    result_mask.add(new Mat());
    result_mask.add(new Mat());
    result_mask.add(new Mat());
    result_mask.add(new Mat());

    Core.split(mask_resized, maskChannels);

    Core.bitwise_and(maskChannels.get(0),mask_grey, result_mask.get(0));
    Core.bitwise_and(maskChannels.get(1),mask_grey, result_mask.get(1));
    Core.bitwise_and(maskChannels.get(2),mask_grey, result_mask.get(2));
    Core.bitwise_and(maskChannels.get(3),mask_grey, result_mask.get(3));

    Core.merge(result_mask, roi_gray);        

    Core.bitwise_not(mask_grey,mask_grey);

    ArrayList<Mat> srcChannels = new ArrayList<>(4);
    Core.split(src_roi, srcChannels);
    Core.bitwise_and(srcChannels.get(0),mask_grey, result_mask.get(0));
    Core.bitwise_and(srcChannels.get(1),mask_grey, result_mask.get(1));
    Core.bitwise_and(srcChannels.get(2),mask_grey, result_mask.get(2));
    Core.bitwise_and(srcChannels.get(3),mask_grey, result_mask.get(3));

    Core.merge(result_mask, roi_rgb);          

    Core.addWeighted(roi_gray,1, roi_rgb,1,0, roi_rgb); 

    roi_rgb.copyTo(new Mat(src,roi));

    return src;
}

src.submat(roi)不等于src(roi)在 C++ 中。因为在 C++ 中src(roi)实际上修改的是src数据矩阵在 roi 区域但在 java 中submat正在克隆 src 的 roi。因此对 roi 所做的任何更改都不会影响 src,这就是为什么您在相机预览中没有任何内容。 要使其正确,您需要使用像 C++ 这样的构造函数 即使用

m1.copyTo(new Mat(src,roi));

代替

 m1.copyTo(src.submat(roi));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV 相机预览中未显示蒙版 的相关文章

  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用
  • 上下文敏感与歧义

    我对上下文敏感性和歧义如何相互影响感到困惑 我认为正确的是 歧义 歧义语法会导致使用左推导或右推导构建多个解析树 所有可能的语法都是二义性的语言是二义性语言 例如 C 是一种不明确的语言 因为 x y 总是可以表示两个不同的事物 如下所述
  • 如何在 Blackberry Cascades 中显示具有特定号码的电话板

    我正在使用带有 C QT 和 QML 的 Blackberry Cascades 10 Beta 3 SDK 以及 Blackberry 10 Dev Alpha Simulator 和 QNX Momentics IDE 并且我正在尝试实
  • Android:从 PhoneGap 应用打开 Play 商店链接

    我想从我的phonegap 3 4 应用程序打开一个指向Google Play 商店的链接 呼唤market details id com google android apps maps导致 ActivityNotFoundExcepti
  • 如何获取Android中的所有主屏幕?

    我是安卓开发新手 我知道每个主屏幕都是启动器中的一个工作区 我想获取屏幕上所有应用程序图标的所有位置信息 那么有没有办法获取这些屏幕对象及其图标信息的列表 ADD 我更期待的是应用程序图标和屏幕之间的关系 例如 我想要某个应用程序图标的位置
  • 等待线程完成

    private void button1 Click object sender EventArgs e for int i 0 i lt 15 i Thread nova new Thread Method nova Start list
  • SimpleDateFormat 无法解析的日期 如果语言环境为 ES,则会出现错误。推特“创建时间”

    我正在尝试将 Twitter created at 转换为阿根廷日期时间 如果我这样做 final String TWITTER EEE MMM dd HH mm ss SimpleDateFormat sf new SimpleDateF
  • 在 REST Web 服务中接受逗号分隔值

    我正在尝试接收 REST URI 中以逗号分隔值形式的字符串列表 示例 http localhost 8080 com vogella jersey first rest todo test 1 abc test 其中 abc 和 test
  • ASTParser:解析绑定后查找声明节点

    我创建了一个启用了绑定的 AST 当我稍后解析绑定时 我得到了一个有效的 ITypeBinding 但是 当我想要获取绑定的声明 Node 时 它 总是返回 null 除非 ITypeBinding 在 sourceFile 中声明 这是我
  • .NET中的LinkedList是循环链表吗?

    我需要一个循环链表 所以我想知道是否LinkedList是循环链表吗 每当您想要移动列表中的 下一个 块时 以循环方式使用它的快速解决方案 current current Next current List First 电流在哪里Linke
  • Android - 检测视图上的双击和三次点击

    我一直在尝试构建一个可以检测双敲击和三敲击的敲击检测器 在我的努力失败后 我在网上搜索了很长时间以找到可以使用的东西 但没有运气 奇怪的是 像这样的图书馆如此稀缺 有什么帮助吗 你可以尝试这样的事情 尽管我通常建议不要使用三次点击作为一种模
  • Struts2中的变量声明

    Struts2中如何声明变量并为该变量赋值 使用设置标签
  • 如何在 Log4j2 - JSON 布局中自定义或删除默认属性

    In Spring Boot 2我已配置的应用程序Log4j2 with JsonLayout像下面这样
  • Lucene/Hibernate 搜索锁定异常

    我使用 Hibernate Search 在 Web 应用程序上索引和全文搜索项目 没有问题 来自我的 pom xml
  • 使用 OpenCV 进行三角形检测

    我有以下示例图像 我想用白色填充角落里的这些三角形 我如何使用 OpenCV 检测它们 当然 在这个特定的示例中 我可以只依靠渐变或亮度 然而 未来图像的形状不会如此完美 所以我正在考虑一些形状检测 我听说形状通常可以通过例如霍夫变换来检测
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 编译时“strlen()”有效吗?

    有时需要将字符串的长度与常量进行比较 例如 if line length gt 2 Do something 但我试图避免在代码中使用 魔法 常量 通常我使用这样的代码 if line length gt strlen Do somethi
  • 如何列出Resources文件夹中的所有文件(java/scala)

    我正在编写一个函数 需要访问资源中的文件夹 并循环遍历所有文件名 如果这些文件符合条件 则加载这些文件 new File getClass getResource images sprites getPath listFiles 返回空指针
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • 如何将 Roslyn 语义模型返回的类型符号名称与 Mono.Cecil 返回的类型符号名称相匹配?

    我有以下代码 var paramDeclType m semanticModel GetTypeInfo paramDecl Type Type Where paramDeclType ToString returns System Col

随机推荐