2012-02-12 17 views
8

मैं एक एंड्रॉइड फोन का उपयोग कर एक रोबोटिक्स प्रोजेक्ट पर काम कर रहा हूं क्योंकि मुख्य प्रोसेसर और कैमरा आंदोलन का पता लगाने के लिए है। मुझे Android binary package from OpenCV मिला और इसे सही ढंग से इंस्टॉल किया गया। मैं ओपनसीवी देशी कैमरे का उपयोग कर छवियों को कैप्चर कर सकता हूं और उन्हें स्क्रीन पर प्रदर्शित कर सकता हूं। हालांकि, मुझे पृष्ठभूमि घटाव वर्ग का उपयोग करने में समस्याएं आ रही हैं। मैं कन्स्ट्रक्टर में एक नया BackgroundSubtractorMOG ऑब्जेक्ट बना सकता हूं, लेकिन जब मैं नीचे दिए गए कोड को चलाने का प्रयास करता हूं, तो यह निकलता है कि मुझे मूल कोड से "केवल 1- और 3-चैनल 8-बिट छवियों को BackgroundSubtractorMOG" में त्रुटि मिलती है। मैंने Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA को Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB में बदलने का प्रयास किया, और फिर यह छोड़ने को मजबूर नहीं करता है, लेकिन मुझे जो भी मिलता है वह एक ब्लैक स्क्रीन है। मुझे यकीन है कि बीएमपी अभी भी FRAME_RGB के साथ शून्य है, क्योंकि स्क्रीन काला रहता है, और fps काउंटर मैं बिटमैप के बाद सही चित्रित कर रहा था (स्पष्टता के लिए नीचे दिए गए कोड से हटाया गया और समस्या निवारण चरण के रूप में) दिखाई नहीं देता है।ओपनसीवी एंड्रॉइड पृष्ठभूमि घटाव

मैं इस समारोह (line 388 here) के लिए OpenCV सी ++ कोड पर एक नज़र ले लिया, और छवि प्रकार त्रुटि तब होती है, तो छवि प्रकार CV_8UC1 या CV_8UC3 नहीं है, इसलिए मैं highgui के बजाय जावा CvType.CV_8UC3 उपयोग करने की कोशिश। CV_CAP_ANDROID_COLOR_FRAME_RGBA कैप्चर. पुनर्प्राप्ति() में, लेकिन यह बंद हो गया और मुझे "आउटपुट फ्रेम प्रारूप समर्थित नहीं है" त्रुटि मिली।

मुझे लगता है कि मुझे अभी एक प्रकार की रूपांतरण समस्या मिली है, लेकिन मैं अपने जीवन के बारे में नहीं समझ सकता हूं जहां ओपनसीवी के एंड्रॉइड-विशिष्ट छवि प्रकार उनके नियमित छवि प्रकारों के साथ फिट होते हैं जो दस्तावेज हैं। किसी भी सहायता की सराहना की जाएगी।

चर:

private SurfaceHolder mHolder; 
private VideoCapture mCamera; 
private Mat mRgba; 
private Mat mFGMask; 
private BackgroundSubtractorMOG mBGSub; 

मेरे SurfaceView की दौड़() फ़ंक्शन:

public void run() {  
    Bitmap bmp = null; 

    synchronized (this) { 
     if (mCamera == null) 
      break; 

     if (!mCamera.grab()) { 
      Log.e(TAG, "mCamera.grab() failed"); 
      break; 
     } 

     processFrame(mCamera); 
     bmp = Bitmap.createBitmap(mFGMask.cols(), mFGMask.rows(), Bitmap.Config.ARGB_8888); 
     Utils.matToBitmap(mFGMask, bmp); 
    } 

    if (bmp != null) { 
     Canvas canvas = mHolder.lockCanvas(); 
     if (canvas != null) { 
      canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth())/2, (canvas.getHeight() - bmp.getHeight())/2, null); 
      mHolder.unlockCanvasAndPost(canvas); 
     } 
     bmp.recycle(); 
    } 
} 

processFrame() फ़ंक्शन रन() में संदर्भित:

protected void processFrame(VideoCapture capture) { 
    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); 
    mBGSub.apply(mRgba, mFGMask); 
} 

संपादित करें:

समाधान है कि काम कर समाप्त हो गया:

protected void processFrame(VideoCapture capture) { 
    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB); 
    //GREY_FRAME also works and exhibits better performance 
    //capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_GREY_FRAME); 
    mBGSub.apply(mRgba, mFGMask, 0.1); 
    Imgproc.cvtColor(mFGMask, mRgba, Imgproc.COLOR_GRAY2BGRA, 4); 
} 

उत्तर

3

आप CV_RGB2RGBA और CV_RGBA2RGB साथ cvtColor उपयोग करने की कोशिश है। तो, शायद फ्रेम आरजीबीए को आरजीबी में परिवर्तित करने का प्रयास करें, फिर पृष्ठभूमि घटाएं। कुछ इस तरह:

protected void processFrame(VideoCapture capture) { 
    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); 
    Mat rgb; 
    Imgproc.cvtColor(mRgba, rgb, Imgproc.COLOR_RGBA2RGB); 
    mBGSub.apply(rgb, mFGMask); 
} 

संपादित करें: आप BackgroundSubtractorMOG के लिए OpenCV इकाई परीक्षण here स्थित की जाँच हो सकता है। हालांकि, मुख्य परीक्षण मामले में परीक्षण fail("Not yet implemented"); है।

मुझे यकीन नहीं है कि इसका मतलब है कि परीक्षण पूरा नहीं हुआ है, या BackgroundSubtractorMOG के लिए समर्थन लागू नहीं किया गया है। आप यह यूनिट-टेस्ट में निहित कोड को चलाने का प्रयास कर सकते हैं यह देखने के लिए कि यह वास्तव में काम करता है या नहीं।

इसके अलावा, सी ++ नमूना segment_objects.cpp उपयोग उदाहरण के रूप में सहायक हो सकता है।

आशा है कि मदद करता है! :)

+0

यह मुझे करीब ले जाता है। जावा-लिपटे संस्करण के लिए सटीक वाक्यविन्यास यह है: 'Imgproc.cvtColor (mRgba, rgb, Imgproc.COLOR_RGBA2RGB);' पहले कनवर्ट के लिए, और दूसरे की आवश्यकता नहीं है (मैं कच्ची छवि के साथ कुछ भी नहीं कर रहा हूं घटाव के बाद)। अब, मुझे एक ब्लैक स्क्रीन मिलती है (कोई बल बंद नहीं होता है)। अगर मैं बिटमैप प्रारूप को बिटमैप में बदलता हूं। कॉनफिग.आरजीबी_565, मुझे अपना एफपीएस काउंटर वापस मिल जाता है, इसलिए मुझे पता है कि यह चल रहा है, लेकिन यह अभी भी एक ब्लैक स्क्रीन है। हालांकि, मुझे थोड़ा आगे पाने के लिए धन्यवाद। – RedPeasant

+0

@RedPeasant सही वाक्यविन्यास पर जानकारी के लिए धन्यवाद। मैंने इसे शामिल करने के लिए अपना जवाब अपडेट कर लिया है। कैमरा चल रहा है और स्क्रीन अभी भी काला है? – mevatron

+0

@RedPeasant मैंने 'BackgroundSubtractorMOG' पर अधिक जानकारी शामिल करने के लिए अपना उत्तर अपडेट किया है। – mevatron

1

धन्यवाद आप लोग बहुत ज्यादा! और भविष्य के दर्शकों के लिए जो इस पृष्ठ पर आते हैं, आपको चीजों को काम करने के लिए इस ज्ञान को ट्विक करना पड़ सकता है। एसडीके v2.4.4 में मैंने इसे कैमरेफ्रेम विधि पर लागू किया। याद रखें कि विधि कैमरे से एक इनपुट फ्रेम में लेता है।आप इनपुट का उपयोग करते हैं और फ्रेम को वापस अपने एंड्रॉइड डिवाइस की स्क्रीन पर प्रदर्शित करते हैं। यहाँ एक उदाहरण है:

//Assume appropriate imports  
private BackgroundSubtractorMOG sub = new BackgroundSubtractorMOG(3, 4, 0.8); 
private Mat mGray = new Mat(); 
private Mat mRgb = new Mat(); 
private Mat mFGMask = new Mat(); 

public Mat onCameraFrame(CvCameraViewFrame inputFrame) { 
    mGray = inputFrame.gray(); //I chose the gray frame because it should require less resources to process 
    Imgproc.cvtColor(mGray, mRgb, Imgproc.COLOR_GRAY2RGB); //the apply function will throw the above error if you don't feed it an RGB image 
    sub.apply(mRgb, mFGMask, learningRate); //apply() exports a gray image by definition 

    return mFGMask; 
} 

ग्रे छवि आता है कि बाहर के लागू (के बारे में मेरी बात भर में प्राप्त करने के लिए), यदि आप एक RGBA संस्करण करना चाहते थे, तो आप कॉल के बाद एक cvtcolor उपयोग करने के लिए लागू करने के लिए हो सकता है ():

private Mat mRgba = new Mat(); 

public Mat onCameraFrame(CvCameraViewFrame inputFrame) { 
    mRgba = inputFrame.rgba(); 
    Imgproc.cvtColor(mRgba, mRgb, Imgproc.COLOR_RGBA2RGB); //the apply function will throw the above error if you don't feed it an RGB image 
    sub.apply(mRgb, mFGMask, learningRate); //apply() exports a gray image by definition 
    Imgproc.cvtColor(mFGMask, mRgba, Imgproc.COLOR_GRAY2RGBA); 

    return mRgba; 
} 
+0

मुझे पृष्ठभूमि SubtractorMOG निर्माता के लिए मूल्यों का चयन करने के बारे में अनिश्चितता है। मैंने उन्हें एक और थ्रेड पर देखा। अपने आवेदन को बेहतर तरीके से फिट करने के लिए मूल्यों के साथ खेलना सुनिश्चित करें। – austin

0

नवीनतम openCV आप के साथ प्रारंभ करने की आवश्यकता के साथ इसके अलावा:)

निजी BackgroundSubtractorMOG2 उप = Video.createBackgroundSubtractorMOG2 (;