簡體   English   中英

Java多線程:將攝像機框架傳遞給正在運行的工作線程

[英]Java multithreading: Passing camera frame to running worker thread

我正在使用OpenCV4Android並捕獲相機幀,因此每次捕獲幀時,都會調用Mat onCameraFrame(CvCameraViewFrame inputFrame)方法。 在該方法內部,我在Mat對象( mRgba )中接收幀。

單擊一個按鈕后,我開始將這些幀發送到連接的FTP服務器。 再次單擊該按鈕后,我將停止發送幀。 我需要將其放在單獨的線程上,因為發送這些幀會導致很多GUI滯后。

我正在努力進行概念化和編碼的工作是...能夠使一個線程在單擊按鈕時啟動和停止,並初始化和啟動線程一次-啟動后,從攝像機接收每個攝像機框架並推動該攝像機框架到FTP服務器。

目前我有這個:

public class FdActivity extends Activity implements CvCameraViewListener2 { 

    private FTPImage ftp;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //connect to FTP server
        ftp = new FTPImage();   

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                String ftpResult = ftp.connectToFTP(config.getFtpIP());
            }
        };
        new Thread(runnable).start();       
    }

    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        mRgba = inputFrame.rgba();
        mGray = inputFrame.gray();

        if (isRecordFrames) {       
            Bitmap bmp;
            try {
                //convert Mat to Bitmap
                bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);         
                Utils.matToBitmap(mRgba, bmp);  
                //scale down Bitmap
                final Bitmap scaledBmp = Bitmap.createScaledBitmap(bmp, bmp.getWidth()/2, bmp.getHeight()/2, false);

                //issue - this is going to create a Runnable for each frame     
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        ftp.writeImageToFTP(scaledBmp);
                    }
                };
                new Thread(runnable).start();   
            }
            catch(Exception ex) {
                Log.i(TAG, "Exception onCameraFrame");
            }
        }   
        return mRgba;
    }
}

FTPImage類別:

public class FTPImage {

    private FTPClient ftpClient = null;

    public String connectToFTP(String ftpIP) {
        ftpClient = new FTPClient();
        String reply = "";

        try {
            ftpClient.connect(InetAddress.getByName(ftpIP));

            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                ftpClient.disconnect();
            }       
            ftpClient.enterLocalPassiveMode();          
            ftpClient.login("anonymous", "");       
            reply = ftpClient.getReplyString();         

        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                }
                catch (IOException ex)
                { }
            }
            e.printStackTrace();
        }
        return reply;
    }

    public void writeImageToFTP(Bitmap b) {
        if (ftpClient != null) {
            if (ftpClient.isConnected()) {
                try {
                    boolean res = ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

                    ByteArrayOutputStream stream = new ByteArrayOutputStream();         
                    b.compress(CompressFormat.PNG, 100, stream);

                    BufferedInputStream buffIn = new BufferedInputStream(
                            new ByteArrayInputStream(stream.toByteArray()));

                    res = ftpClient.storeFile("testImg.jpg", buffIn);
                    //when res returns, storeFile has finished uploading
                    String reply = ftpClient.getReplyString();

                    buffIn.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void disconnectFromFTP() {
        try {
            if (ftpClient.isConnected()) {
                ftpClient.logout(); 
                ftpClient.disconnect();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

如何將每個攝像機幀傳遞到一個單獨的運行線程,然后將該線程發送到FTP服務器?

我希望這是有道理的……只是在穿線部分遇到了麻煩。 先感謝您!

我試圖在這里添加線程UploadThread:

public class FdActivity extends Activity implements CvCameraViewListener2 { 

private FTPImage ftp;

// declaration
private UploadThread mUploadThread;
private Handler mUploadHandler;
public static int UPLOAD_IMAGE = 11;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
// initialization
mUploadThread = new UploadThread(this);
mUploadThread.start();
    //connect to FTP server
    ftp = new FTPImage();   

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            String ftpResult = ftp.connectToFTP(config.getFtpIP());
        }
    };
    new Thread(runnable).start();       
}

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    mRgba = inputFrame.rgba();
    mGray = inputFrame.gray();

    if (isRecordFrames) {       
        Bitmap bmp;
        try {
            //convert Mat to Bitmap
            bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);         
            Utils.matToBitmap(mRgba, bmp);  
            //scale down Bitmap
            final Bitmap scaledBmp = Bitmap.createScaledBitmap(bmp, bmp.getWidth()/2, bmp.getHeight()/2, false);



    Message msg = Message.obtain();
    msg.what = UPLOAD_IMAGE;
    mUploadHandler.sendMessage(msg);    // this way we send message to upload thread queue
        }
        catch(Exception ex) {
            Log.i(TAG, "Exception onCameraFrame");
        }
    }   
    return mRgba;
}

Thread UploadThread = new Thread() {
    private Context;
    public UploadThread(Context context) {
        this.context = context;
    }
    @Override
    public void run() {
        Looper.prepare();
        mUploadHandler = new Handler() {
            public void handleMessage(msg) {
                case UPLOAD_IMAGE:
                ftp.writeImageToFTP(scaledBmp);     // uploading    
                break;              
            }
        }               


        Looper.loop();

        }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM