gpt4 book ai didi

java - OpenCV 相机预览中未显示 mask

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:12:32 25 4
gpt4 key购买 nike

我想制作一个简单的 Android 应用程序,用 OpenCV 在检测到的脸上戴上面具,例如这个例子:

Mask on face detection tutorial

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

Screenshot of the result

我的代码:

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

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

代替

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

关于java - OpenCV 相机预览中未显示 mask ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38749867/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com