1

この質問は尋ねられましたが、ここで答えられることはありませんでした- とにかく、それは私の必要性とは多少異なります.

バックグラウンドで Google Vision ライブラリを実行しながらビデオを録画したいので、ユーザーがバーコードを持ち上げる (またはバーコードに十分に近づける) たびに、カメラはバーコードを自動的に検出してスキャンします。ビデオ。Google Vision のデモがかなり CPU を集中的に使用することはわかっていますが、より単純なバージョン (つまり、すべてのフレームを常に取得して検出器に渡さない) を試してみると、信頼できるバーコード読み取りが得られません。

(私は KitKat 4.4.3 で Samsung Galaxy S4 Mini を実行しています。残念ながら、Samsung だけが知っている理由により、彼らは OnCameraFocused イベントを報告しなくなりました。そのため、カメラがフォーカスをつかんでバーコードを読み取ったかどうかを知ることは不可能です。そのため、すべてのフレームを取得してチェックすることが唯一の実行可能な解決策のように思えます。)

したがって、少なくともその概念を証明するために、Google Vision Demo を単純に変更したいと考えました。(ここにあります)

最も簡単な方法は、コードに飛び込んでメディア レコーダーを追加することです。これは、サーフェスの作成中に CameraSourcePreview メソッドで行いました。

このような:

private class SurfaceCallback implements SurfaceHolder.Callback
{
    @Override
    public void surfaceCreated(SurfaceHolder surface)
    {
        mSurfaceAvailable = true;
        try
        {
            startIfReady();
            if (mSurfaceAvailable)
            {
                Camera camera = mCameraSource.getCameraSourceCamera();
                /** ADD MediaRecorder to Google Example  **/
                if (camera != null && recordThis)
                {
                    if (mMediaRecorder == null)
                    {
                        mMediaRecorder = new MediaRecorder();
                        camera.unlock();
                        SurfaceHolder sh = mSurfaceView.getHolder();
                        mMediaRecorder.setPreviewDisplay(sh.getSurface());
                        mMediaRecorder.setCamera(camera);
                        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
                        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
                        mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
                        String OutputFile = Environment.getExternalStorageDirectory() + "/" +
                                DateFormat.format("yyyy-MM-dd_kk-mm-ss", new Date().getTime()) + ".mp4";
                        File newOutPut = getVideoFile();
                        String newOutPutFileName = newOutPut.getPath();
                        mMediaRecorder.setOutputFile(newOutPutFileName);
                        Log.d("START MR", OutputFile);
                        try { mMediaRecorder.prepare(); } catch (Exception e) {}
                        mCameraSource.mediaRecorder = mMediaRecorder;
                        mMediaRecorder.start();
                    }
                }
            }
        }
        catch (SecurityException se)
        {
            Log.e(TAG, "Do not have permission to start the camera", se);
        }
        catch (IOException e)
        {
            Log.e(TAG, "Could not start camera source.", e);
        }
    }

各フレームをビジョンコードに渡しながら、それは物事を記録します。しかし、奇妙なことに、私がそうすると、カメラはオートフォーカスを正しく呼び出していないようで、バーコードはスキャンされません。

次に考えたのは、バーコード検出器がフレームを処理しているときにフレームを単純にキャプチャし、それらを 1 つずつディスクに保存することでした (後でそれらを一緒に多重化できます)。

これは CameraSource.java で行いました。

バックグラウンドで実行されている別の AsyncTask でそれらを書き込んでいるにもかかわらず、これはすべてのフレームをキャプチャしていないようです.追いつくのに時間がかかったとしても. 保存は最適化されていませんが、最後だけでなく全体でフレームが落ちているように見えます。

このコードを追加するために、run() メソッドのプライベート クラス FrameProcessingRunnable に入れてみました。

FrameBuilder コードの直後に、これを追加しました。

            if (saveImagesIsEnabled)
            {
                if (data == null)
                {
                    Log.d(TAG, "data == NULL");
                }
                else
                {
                    SaveImageAsync saveImage = new SaveImageAsync(mCamera.getParameters().getPreviewSize() );
                    saveImage.execute(data.array());
                }
            }

このクラスを呼び出すもの:

Camera.Size lastKnownPreviewSize = null;
public class SaveImageAsync extends AsyncTask<byte[], Void, Void>
{
    Camera.Size previewSize;

    public SaveImageAsync(Camera.Size _previewSize)
    {
        previewSize = _previewSize;
        lastKnownPreviewSize = _previewSize;
    }
    @Override
    protected Void doInBackground(byte[]... dataArray)
    {
        try
        {
            if (previewSize == null)
            {
                if (lastKnownPreviewSize != null)
                    previewSize = lastKnownPreviewSize;
                else
                    return null;
            }
            byte[] bitmapData = dataArray[0];
            if (bitmapData == null)
            {
                Log.d("doInBackground","NULL: ");
                return null;
            }
                // where to put the output file (note: /sdcard requires WRITE_EXTERNAL_STORAGE permission)
                File storageDir = Environment.getExternalStorageDirectory();
                String imageFileName = baseFileName + "_" +  Long.toString(sequentialCount++) + ".jpg";
                String filePath = storageDir + "/" + "tmp" + "/" + imageFileName;
                FileOutputStream out = null;
                YuvImage yuvimage = new YuvImage(bitmapData, ImageFormat.NV21, previewSize.width,
                        previewSize.height, null);
            try
            {
                out = new FileOutputStream(filePath);
                yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width,
                        previewSize.height), 100, out);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                try
                {
                    if (out != null)
                    {
                        out.close();
                    }
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            Log.d("doInBackground", ex.getMessage());
        }
        return null;
    }
}

mediarecorder のアイデア、またはブルート フォース フレーム キャプチャのアイデアには問題ありませんが、どちらも正しく機能していないようです。

4

0 に答える 0