opencv - 从 hbase 读取图像并使用 Opencv 检测该图像中的人脸

标签 opencv hadoop hbase hipi

我需要读取 hbase 中的图像并转换为 opencv mat 以进行人脸检测。
我的代码如下

public static class FaceCountMapper extends TableMapper<Text, Text> {
private CascadeClassifier faceDetector;

public void setup(Context context) throws IOException, InterruptedException {

    if (context.getCacheFiles() != null && context.getCacheFiles().length > 0) {
        URI mappingFileUri = context.getCacheFiles()[0];

        if (mappingFileUri != null) {
            System.out.println(mappingFileUri);
            faceDetector = new CascadeClassifier(mappingFileUri.toString());

        }
    }

    super.setup(context);
} // setup()

public ArrayList<Object> detectFaces(Mat image, String file_name) {

    ArrayList<Object> facemap = new ArrayList<Object>();

    MatOfRect faceDetections = new MatOfRect();

    faceDetector.detectMultiScale(image, faceDetections);

    System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
    output.put(faceDetections.toArray().length);

    facemap.add(output);

}

return facemap;

}

public void map(ImmutableBytesWritable row, Result result, Context context)
        throws InterruptedException, IOException {

    String file_name = Bytes.toString(result.getValue(Bytes.toBytes("Filename"), Bytes.toBytes("data")));

    String mimetype = Bytes.toString(result.getValue(Bytes.toBytes("mime"), Bytes.toBytes("data")));

    byte[] image_data = result.getValue(Bytes.toBytes("Data"), Bytes.toBytes("data"));

    BufferedImage bi = ImageIO.read(new ByteArrayInputStream(image_data));

    Mat mat = new Mat(bi.getHeight(), bi.getWidth(), CvType.CV_8UC3);

    mat.put(0, 0, image_data);
    detectFaces(mat, file_name);

}

作业配置如下

Configuration conf = this.getConf();
    conf.set("hbase.master", "101.192.0.122:16000");
    conf.set("hbase.zookeeper.quorum", "101.192.0.122");
    conf.setInt("hbase.zookeeper.property.clientPort", 2181);
    conf.set("zookeeper.znode.parent", "/hbase-unsecure");

    // Initialize and configure MapReduce job
    Job job = Job.getInstance(conf);

    job.setJarByClass(FaceCount3.class);
    job.setMapperClass(FaceCountMapper.class);
    job.getConfiguration().set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
    job.getConfiguration().set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName());

    Scan scan = new Scan();
    scan.setCaching(500); // 1 is the default in Scan, which will be bad for
                            // MapReduce jobs
    scan.setCacheBlocks(false); // don't set to true for MR jobs

    TableMapReduceUtil.initTableMapperJob("Image", // input HBase table name
            scan, // Scan instance to control CF and attribute selection
            FaceCountMapper.class, // mapper
            null, // mapper output key
            null, // mapper output value
            job);
    job.setOutputFormatClass(NullOutputFormat.class); // because we aren't
                                                        // emitting anything
                                                        // from mapper

    job.addCacheFile(new URI("/user/hduser/haarcascade_frontalface_alt.xml"));
    job.addFileToClassPath(new Path("/user/hduser/hipi-2.1.0.jar"));
    job.addFileToClassPath(new Path("/user/hduser/javacpp.jar"));
    DistributedCache.addFileToClassPath(new Path("/user/hduser/haarcascade_frontalface_alt.xml"), conf);
    conf.set("mapred.job.tracker", "local");
    // Execute the MapReduce job and block until it complets
    boolean success = job.waitForCompletion(true);

    // Return success or failure
    return success ? 0 : 1;

运行时我得到

java.lang.Exception: java.lang.UnsatisfiedLinkError: org.opencv.objdetect.CascadeClassifier.CascadeClassifier_1(Ljava/lang/String;)J

错误。

但是Opencv.jar在hadoop_classpath中提供

最佳答案

当应用程序尝试加载 native 库时抛出 UnsatisfiedLinkError,例如 Linux 中的 .so、Windows 中的 .dll.dylib在 Mac 中,该库不存在。具体来说,为了找到所需的 native 库,JVM 会同时查看 PATH 环境变量和 java.library.path 系统属性。

此外,如果您的应用程序已经加载了该库,并且该应用程序尝试再次加载它,则 JVM 将抛出 UnsatisfiedLinkError此外,您必须验证 native 库是否存在于 java.library.path 或应用程序的 PATH 环境库中。如果仍然找不到库,请尝试提供 System.loadLibrary 方法的绝对路径。

在您的情况下,请尝试调用方的以下方法并查看类路径元素是什么。

/**
     * Method printClassPathResources.
     */
    public static void printClassPathResources() {
        final ClassLoader cl = ClassLoader.getSystemClassLoader();
        final URL[] urls = ((URLClassLoader) cl).getURLs();
        LOG.info("Print All Class path resources under currently running class");
        for (final URL url : urls) {
            LOG.info(url.getFile());
        }

    }

根据这些输入,您可以调整您的类路径条目(在本例中为 opencv jar 或其他东西)并查看是否有效。

关于opencv - 从 hbase 读取图像并使用 Opencv 检测该图像中的人脸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37342832/

相关文章:

scala - 使用 Spark Scala 将 HDFS 文件内容存储在 ArrayBuffer 中

java - 从mongoDB复制数据到hdfs时hadoop jar错误

HBase 扫描 - RowKey 过滤器

opencv - 为两个Visual Studio版本安装两个OpenCv版本?

opencv - 如何在 OpenCV 中定义分水岭标记?

matlab - 如何估计/确定深度图像点的表面法线和切平面?

hadoop - 减少 Hive 查询执行时间的方法

hbase - 表在 HBase 中既不启用也不禁用

java - 如何覆盖特定类的log4j设置

javascript - 我的 javascript 代码有什么问题还是 opencv.js?