ओपन सीवी फेस रिकग्निशन सटीक नहीं है


13

अपने एप्लिकेशन में मैं ओपन सीवी का उपयोग करके एक विशिष्ट छवि पर चेहरा पहचान करने की कोशिश कर रहा हूं, यहां पहले मैं एक छवि को प्रशिक्षित कर रहा हूं और फिर उस छवि को प्रशिक्षित करने के बाद अगर मैं उस छवि पर चेहरा पहचान को चलाता हूं तो यह सफलतापूर्वक उस प्रशिक्षित चेहरे को पहचानता है। हालाँकि, जब मैं उसी व्यक्ति की किसी अन्य तस्वीर को चालू करता हूं तो मान्यता काम नहीं करती है। यह सिर्फ प्रशिक्षित छवि पर काम करता है, इसलिए मेरा सवाल यह है कि मैं इसे कैसे ठीक करूं?

अपडेट: मैं क्या करना चाहता हूं कि उपयोगकर्ता को भंडारण से किसी व्यक्ति की छवि का चयन करना चाहिए और फिर उस चयनित छवि को प्रशिक्षित करने के बाद मैं भंडारण से सभी छवियों को प्राप्त करना चाहता हूं जो मेरी प्रशिक्षित छवि के चेहरे से मेल खाती है

यहाँ मेरी गतिविधि कक्षा है:

public class MainActivity extends AppCompatActivity {
    private Mat rgba,gray;
    private CascadeClassifier classifier;
    private MatOfRect faces;
    private ArrayList<Mat> images;
    private ArrayList<String> imagesLabels;
    private Storage local;
    ImageView mimage;
    Button prev,next;
    ArrayList<Integer> imgs;
    private int label[] = new int[1];
    private double predict[] = new double[1];
    Integer pos = 0;
    private String[] uniqueLabels;
    FaceRecognizer recognize;
    private boolean trainfaces() {
        if(images.isEmpty())
            return false;
        List<Mat> imagesMatrix = new ArrayList<>();
        for (int i = 0; i < images.size(); i++)
            imagesMatrix.add(images.get(i));
        Set<String> uniqueLabelsSet = new HashSet<>(imagesLabels); // Get all unique labels
        uniqueLabels = uniqueLabelsSet.toArray(new String[uniqueLabelsSet.size()]); // Convert to String array, so we can read the values from the indices

        int[] classesNumbers = new int[uniqueLabels.length];
        for (int i = 0; i < classesNumbers.length; i++)
            classesNumbers[i] = i + 1; // Create incrementing list for each unique label starting at 1
        int[] classes = new int[imagesLabels.size()];
        for (int i = 0; i < imagesLabels.size(); i++) {
            String label = imagesLabels.get(i);
            for (int j = 0; j < uniqueLabels.length; j++) {
                if (label.equals(uniqueLabels[j])) {
                    classes[i] = classesNumbers[j]; // Insert corresponding number
                    break;
                }
            }
        }
        Mat vectorClasses = new Mat(classes.length, 1, CvType.CV_32SC1); // CV_32S == int
        vectorClasses.put(0, 0, classes); // Copy int array into a vector

        recognize = LBPHFaceRecognizer.create(3,8,8,8,200);
        recognize.train(imagesMatrix, vectorClasses);
        if(SaveImage())
            return true;

        return false;
    }
    public void cropedImages(Mat mat) {
        Rect rect_Crop=null;
        for(Rect face: faces.toArray()) {
            rect_Crop = new Rect(face.x, face.y, face.width, face.height);
        }
        Mat croped = new Mat(mat, rect_Crop);
        images.add(croped);
    }
    public boolean SaveImage() {
        File path = new File(Environment.getExternalStorageDirectory(), "TrainedData");
        path.mkdirs();
        String filename = "lbph_trained_data.xml";
        File file = new File(path, filename);
        recognize.save(file.toString());
        if(file.exists())
            return true;
        return false;
    }

    private BaseLoaderCallback callbackLoader = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch(status) {
                case BaseLoaderCallback.SUCCESS:
                    faces = new MatOfRect();

                    //reset
                    images = new ArrayList<Mat>();
                    imagesLabels = new ArrayList<String>();
                    local.putListMat("images", images);
                    local.putListString("imagesLabels", imagesLabels);

                    images = local.getListMat("images");
                    imagesLabels = local.getListString("imagesLabels");

                    break;
                default:
                    super.onManagerConnected(status);
                    break;
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        if(OpenCVLoader.initDebug()) {
            Log.i("hmm", "System Library Loaded Successfully");
            callbackLoader.onManagerConnected(BaseLoaderCallback.SUCCESS);
        } else {
            Log.i("hmm", "Unable To Load System Library");
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, callbackLoader);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        prev = findViewById(R.id.btprev);
        next = findViewById(R.id.btnext);
        mimage = findViewById(R.id.mimage);
       local = new Storage(this);
       imgs = new ArrayList();
       imgs.add(R.drawable.jonc);
       imgs.add(R.drawable.jonc2);
       imgs.add(R.drawable.randy1);
       imgs.add(R.drawable.randy2);
       imgs.add(R.drawable.imgone);
       imgs.add(R.drawable.imagetwo);
       mimage.setBackgroundResource(imgs.get(pos));
        prev.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(pos!=0){
                  pos--;
                  mimage.setBackgroundResource(imgs.get(pos));
                }
            }
        });
        next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(pos<5){
                    pos++;
                    mimage.setBackgroundResource(imgs.get(pos));
                }
            }
        });
        Button train = (Button)findViewById(R.id.btn_train);
        train.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.KITKAT)
            @Override
            public void onClick(View view) {
                rgba = new Mat();
                gray = new Mat();
                Mat mGrayTmp = new Mat();
                Mat mRgbaTmp = new Mat();
                classifier = FileUtils.loadXMLS(MainActivity.this);
                Bitmap icon = BitmapFactory.decodeResource(getResources(),
                        imgs.get(pos));
                Bitmap bmp32 = icon.copy(Bitmap.Config.ARGB_8888, true);
                Utils.bitmapToMat(bmp32, mGrayTmp);
                Utils.bitmapToMat(bmp32, mRgbaTmp);
                Imgproc.cvtColor(mGrayTmp, mGrayTmp, Imgproc.COLOR_BGR2GRAY);
                Imgproc.cvtColor(mRgbaTmp, mRgbaTmp, Imgproc.COLOR_BGRA2RGBA);
                /*Core.transpose(mGrayTmp, mGrayTmp); // Rotate image
                Core.flip(mGrayTmp, mGrayTmp, -1); // Flip along both*/
                gray = mGrayTmp;
                rgba = mRgbaTmp;
                Imgproc.resize(gray, gray, new Size(200,200.0f/ ((float)gray.width()/ (float)gray.height())));
                if(gray.total() == 0)
                    Toast.makeText(getApplicationContext(), "Can't Detect Faces", Toast.LENGTH_SHORT).show();
                classifier.detectMultiScale(gray,faces,1.1,3,0|CASCADE_SCALE_IMAGE, new Size(30,30));
                if(!faces.empty()) {
                    if(faces.toArray().length > 1)
                        Toast.makeText(getApplicationContext(), "Mutliple Faces Are not allowed", Toast.LENGTH_SHORT).show();
                    else {
                        if(gray.total() == 0) {
                            Log.i("hmm", "Empty gray image");
                            return;
                        }
                        cropedImages(gray);
                        imagesLabels.add("Baby");
                        Toast.makeText(getApplicationContext(), "Picture Set As Baby", Toast.LENGTH_LONG).show();
                        if (images != null && imagesLabels != null) {
                            local.putListMat("images", images);
                            local.putListString("imagesLabels", imagesLabels);
                            Log.i("hmm", "Images have been saved");
                            if(trainfaces()) {
                                images.clear();
                                imagesLabels.clear();
                            }
                        }
                    }
                }else {
                   /* Bitmap bmp = null;
                    Mat tmp = new Mat(250, 250, CvType.CV_8U, new Scalar(4));
                    try {
                        //Imgproc.cvtColor(seedsImage, tmp, Imgproc.COLOR_RGB2BGRA);
                        Imgproc.cvtColor(gray, tmp, Imgproc.COLOR_GRAY2RGBA, 4);
                        bmp = Bitmap.createBitmap(tmp.cols(), tmp.rows(), Bitmap.Config.ARGB_8888);
                        Utils.matToBitmap(tmp, bmp);
                    } catch (CvException e) {
                        Log.d("Exception", e.getMessage());
                    }*/
                    /*    mimage.setImageBitmap(bmp);*/
                    Toast.makeText(getApplicationContext(), "Unknown Face", Toast.LENGTH_SHORT).show();
                }
            }
        });
        Button recognize = (Button)findViewById(R.id.btn_recognize);
        recognize.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(loadData())
                    Log.i("hmm", "Trained data loaded successfully");
                rgba = new Mat();
                gray = new Mat();
                faces = new MatOfRect();
                Mat mGrayTmp = new Mat();
                Mat mRgbaTmp = new Mat();
                classifier = FileUtils.loadXMLS(MainActivity.this);
                Bitmap icon = BitmapFactory.decodeResource(getResources(),
                        imgs.get(pos));
                Bitmap bmp32 = icon.copy(Bitmap.Config.ARGB_8888, true);
                Utils.bitmapToMat(bmp32, mGrayTmp);
                Utils.bitmapToMat(bmp32, mRgbaTmp);
                Imgproc.cvtColor(mGrayTmp, mGrayTmp, Imgproc.COLOR_BGR2GRAY);
                Imgproc.cvtColor(mRgbaTmp, mRgbaTmp, Imgproc.COLOR_BGRA2RGBA);
                /*Core.transpose(mGrayTmp, mGrayTmp); // Rotate image
                Core.flip(mGrayTmp, mGrayTmp, -1); // Flip along both*/
                gray = mGrayTmp;
                rgba = mRgbaTmp;
                Imgproc.resize(gray, gray, new Size(200,200.0f/ ((float)gray.width()/ (float)gray.height())));
                if(gray.total() == 0)
                    Toast.makeText(getApplicationContext(), "Can't Detect Faces", Toast.LENGTH_SHORT).show();
                classifier.detectMultiScale(gray,faces,1.1,3,0|CASCADE_SCALE_IMAGE, new Size(30,30));
                if(!faces.empty()) {
                    if(faces.toArray().length > 1)
                        Toast.makeText(getApplicationContext(), "Mutliple Faces Are not allowed", Toast.LENGTH_SHORT).show();
                    else {
                        if(gray.total() == 0) {
                            Log.i("hmm", "Empty gray image");
                            return;
                        }
                        recognizeImage(gray);
                    }
                }else {
                    Toast.makeText(getApplicationContext(), "Unknown Face", Toast.LENGTH_SHORT).show();
                }
            }
        });


    }
    private void recognizeImage(Mat mat) {
        Rect rect_Crop=null;
        for(Rect face: faces.toArray()) {
            rect_Crop = new Rect(face.x, face.y, face.width, face.height);
        }
        Mat croped = new Mat(mat, rect_Crop);
        recognize.predict(croped, label, predict);
        int indice = (int)predict[0];
        Log.i("hmmcheck:",String.valueOf(label[0])+" : "+String.valueOf(indice));
        if(label[0] != -1 && indice < 125)
            Toast.makeText(getApplicationContext(), "Welcome "+uniqueLabels[label[0]-1]+"", Toast.LENGTH_SHORT).show();
        else
            Toast.makeText(getApplicationContext(), "You're not the right person", Toast.LENGTH_SHORT).show();
    }
    private boolean loadData() {
        String filename = FileUtils.loadTrained();
        if(filename.isEmpty())
            return false;
        else
        {
            recognize.read(filename);
            return true;
        }
    }
}

मेरी फाइल बर्तन कक्षा:

   public class FileUtils {
        private static String TAG = FileUtils.class.getSimpleName();
        private static boolean loadFile(Context context, String cascadeName) {
            InputStream inp = null;
            OutputStream out = null;
            boolean completed = false;
            try {
                inp = context.getResources().getAssets().open(cascadeName);
                File outFile = new File(context.getCacheDir(), cascadeName);
                out = new FileOutputStream(outFile);

                byte[] buffer = new byte[4096];
                int bytesread;
                while((bytesread = inp.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesread);
                }

                completed = true;
                inp.close();
                out.flush();
                out.close();
            } catch (IOException e) {
                Log.i(TAG, "Unable to load cascade file" + e);
            }
            return completed;
        }
        public static CascadeClassifier loadXMLS(Activity activity) {


            InputStream is = activity.getResources().openRawResource(R.raw.lbpcascade_frontalface);
            File cascadeDir = activity.getDir("cascade", Context.MODE_PRIVATE);
            File mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface_improved.xml");
            FileOutputStream os = null;
            try {
                os = new FileOutputStream(mCascadeFile);
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = is.read(buffer)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
                is.close();
                os.close();

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }


            return new CascadeClassifier(mCascadeFile.getAbsolutePath());
        }
        public static String loadTrained() {
            File file = new File(Environment.getExternalStorageDirectory(), "TrainedData/lbph_trained_data.xml");

            return file.toString();
        }
    }

ये ऐसे चित्र हैं जो मैं यहाँ व्यक्ति की तुलना करने की कोशिश कर रहा हूँ यह अभी भी मान्यता में है कि यह मेल नहीं खा रहा है! चित्र 1 चित्र 2


जब मैंने ऑटोमैटिक अटेंडेंस सिस्टम के लिए अपना अंतिम वर्ष का असाइनमेंट बनाया, तो मैंने क्लासिफायर को प्रशिक्षित करने के लिए अपने आप को 8-10 छवियों का इस्तेमाल किया।
ZdaR

आप उस आवश्यकता को संभालने के लिए अपनी प्रशिक्षण छवि चटाई को क्षैतिज रूप से फ्लिप कर सकते हैं।
nfl-x

@ nfl-x flipping चित्र सटीकता की समस्या को हल नहीं करेंगे, हमें टेंसरफ़्लो पर हाल ही में कुछ बेहतर उत्तर की आवश्यकता है, ठीक लगता है, लेकिन एंड्रॉइड के लिए इसे लागू करने के लिए पर्याप्त जानकारी या ट्यूटोरियल उपलब्ध नहीं हैं, इसलिए हमारा सबसे अच्छा अनुमान है कि इस पोस्ट को वोट देना जारी रखें इस तरह कि एक विशेषज्ञ हस्तक्षेप कर सकता है और एंड्रॉइड के लिए एक उचित समाधान प्रदान कर सकता है
श्री पटेल

जवाबों:


5

अपडेट करें

प्रश्न में नए संपादन के अनुसार, आपको उस मक्खी पर नए लोगों की पहचान करने का एक तरीका चाहिए, जिसकी तस्वीरें मॉडल के प्रशिक्षण चरण के दौरान उपलब्ध नहीं थीं। इन कार्यों को कुछ शॉट लर्निंग कहा जाता है । यह सीसीटीवी कैमरा फुटेज का उपयोग करके अपने लक्ष्यों को खोजने के लिए खुफिया / पुलिस एजेंसियों की आवश्यकताओं के समान है। जैसा कि आमतौर पर एक विशिष्ट लक्ष्य की पर्याप्त छवियां नहीं होती हैं, प्रशिक्षण के दौरान, वे फेसनेट जैसे मॉडल का उपयोग करते हैं । मैं वास्तव में पेपर पढ़ने का सुझाव देता हूं, हालांकि, मैं यहां इसकी कुछ झलकियां समझाता हूं:

  • आम तौर पर, एक क्लासिफायरियर की अंतिम परत एक * 1 वेक्टर होती है, जिसमें तत्वों का n-1 लगभग शून्य के बराबर होता है, और 1. के करीब एक तत्व, इनपुट के लेबल के बारे में क्लासिफायर की भविष्यवाणी को निर्धारित करता है। विशिष्ट सीएनएन वास्तुकला
  • लेखकों ने यह पता लगाया कि यदि वे चेहरों के विशाल डेटासेट पर एक विशिष्ट नुकसान फ़ंक्शन के साथ एक क्लासिफायर नेटवर्क को प्रशिक्षित करते हैं, तो आप सेमी-फ़ाइनल लेयर आउटपुट का उपयोग किसी भी चेहरे के प्रतिनिधित्व के रूप में कर सकते हैं, चाहे वह प्रशिक्षण सेट में हो या न हो। लेखक इस वेक्टर फेस एंबेडिंग को कहते हैं
  • पिछले परिणाम का मतलब है कि बहुत अच्छी तरह से प्रशिक्षित फेसनेट मॉडल के साथ, आप किसी भी चेहरे को वेक्टर में सारांशित कर सकते हैं। इस दृष्टिकोण की बहुत दिलचस्प विशेषता यह है कि अलग-अलग कोणों / पदों / राज्यों में एक विशिष्ट व्यक्ति के चेहरे के वैक्टर यूक्लिडियन स्पेस में समीपस्थ होते हैं (यह गुण उस हानि फ़ंक्शन द्वारा लागू किया जाता है जिसे लेखकों ने चुना था)।यहां छवि विवरण दर्ज करें
  • सारांश में, आपके पास एक मॉडल है जो इनपुट के रूप में चेहरे पाता है और वैक्टर लौटाता है। एक दूसरे के करीब वैक्टर एक ही व्यक्ति के हैं (यह जाँचने के लिए कि आप KNN या केवल साधारण यूक्लिडियन दूरी का उपयोग कर सकते हैं) से संबंधित हैं।

फेसनेट का एक कार्यान्वयन यहां पाया जा सकता है । मेरा सुझाव है कि आप यह जानने के लिए अपने कंप्यूटर पर इसे चलाने की कोशिश करें कि आप वास्तव में क्या कर रहे हैं। उसके बाद, यह निम्नलिखित करने के लिए सबसे अच्छा हो सकता है:

  1. रिपॉजिटरी में उल्लिखित फेसनेट मॉडल को उसके टैफलाइट संस्करण में बदलना ( यह ब्लॉगपोस्ट मदद कर सकता है)
  2. उपयोगकर्ता द्वारा प्रस्तुत प्रत्येक फोटो के लिए, चेहरे को निकालने के लिए फेस एपीआई का उपयोग करें
  3. निकाले गए चेहरे का चेहरा एम्बेडिंग प्राप्त करने के लिए अपने ऐप में मिनीफाइड मॉडल का उपयोग करें।
  4. उपयोगकर्ता की गैलरी में सभी छवियों को संसाधित करें, फ़ोटो में चेहरे के लिए वैक्टर प्राप्त करें।
  5. फिर स्टेप 4 में पाए जाने वाले प्रत्येक सदिश की तुलना स्टेप 3 में पाए जाने वाले प्रत्येक सदिश से करते हैं।

मूल उत्तर

आप मशीन सीखने की सबसे प्रचलित चुनौतियों में से एक थे: ओवरफिटिंग। फेस डिटेक्शन एंड रिकॉग्निशन अपने आप में शोध का एक बड़ा क्षेत्र है और लगभग सभी सटीक मॉडल किसी न किसी तरह के गहन शिक्षण का उपयोग कर रहे हैं। ध्यान दें कि किसी चेहरे का सही-सही पता लगाना भी उतना आसान नहीं है जितना लगता है, हालाँकि, जैसा कि आप इसे एंड्रॉइड पर कर रहे हैं, आप इस कार्य के लिए फेस एपीआई का उपयोग कर सकते हैं । (अन्य उन्नत तकनीकें जैसे MTCNN किसी हैंडसेट पर तैनात होने के लिए बहुत धीमी / कठिन हैं)। यह दिखाया गया है कि सिर्फ चेहरे की फोटो के साथ मॉडल को खिलाने से पृष्ठभूमि के शोर के साथ या कई लोग अंदर काम नहीं करते हैं। इसलिए, आप वास्तव में इस चरण को छोड़ नहीं सकते।

पृष्ठभूमि से उम्मीदवार के लक्ष्य का अच्छा छंटनी करने के बाद, आपको पहचाने गए चेहरों को पहचानने की चुनौती से पार पाने की आवश्यकता है। फिर से, मेरे ज्ञान का सबसे अच्छा करने के लिए सभी सक्षम मॉडल, किसी प्रकार के गहन सीखने / दृढ़ तंत्रिका नेटवर्क का उपयोग कर रहे हैं। मोबाइल फोन पर उनका उपयोग करना एक चुनौती है, लेकिन टेन्सफ़्लोफ़र्ट लाइट के लिए धन्यवाद आप उन्हें छोटा कर सकते हैं और अपने ऐप के भीतर चला सकते हैं। एंड्रॉइड फोन पर चेहरे की पहचान के बारे में एक परियोजना जो मैंने काम की थी वह यहां है जिसे आप जांच सकते हैं। ध्यान रखें कि किसी भी अच्छे मॉडल को लेबल किए गए डेटा के कई उदाहरणों पर प्रशिक्षित किया जाना चाहिए, हालांकि, पहले से ही चेहरे या अन्य छवि पहचान कार्यों के बड़े डेटासेट पर प्रशिक्षित मॉडल के ढेर सारे हैं, उन्हें ट्विक करने और अपने मौजूदा ज्ञान का उपयोग करने के लिए, हम नियोजित कर सकते हैंट्रांसफर लर्निंग , ऑब्जेक्ट डिटेक्शन पर त्वरित शुरुआत के लिए और ट्रांसफर लर्निंग जो आपके केस से निकटता से संबंधित है, इस ब्लॉग पोस्ट को देखें।

कुल मिलाकर, आपको उन चेहरों के कई उदाहरण प्राप्त करने होंगे, जिन्हें आप उन लोगों के कई चेहरे के चित्रों का पता लगाना चाहते हैं, जिनकी आपको परवाह नहीं है, फिर आपको उपर्युक्त संसाधनों के आधार पर एक मॉडल को प्रशिक्षित करने की आवश्यकता है, और फिर आपको आवश्यकता है अपने आकार को कम करने और इसे अपने ऐप में एम्बेड करने के लिए TensorFlow लाइट का उपयोग करें। तब प्रत्येक फ्रेम के लिए, आप मॉडल में Android फेस एपीआई और फीड (संभवतः ज्ञात चेहरा) को कॉल करते हैं और व्यक्ति की पहचान करते हैं।

देरी के लिए आपकी सहिष्णुता के स्तर और प्रशिक्षण सेट की संख्या और लक्ष्यों की संख्या के आधार पर, आप विभिन्न परिणाम प्राप्त कर सकते हैं, हालांकि, यदि आप केवल कुछ लक्षित लोगों के लिए% 90 + सटीकता आसानी से प्राप्त कर सकते हैं।


मैं अपने ऐप में नेटवर्क कनेक्शन का उपयोग नहीं करना चाहता हूं, इसलिए Google क्लाउड विज़न प्रश्न से बाहर है, लेकिन टेन्सर फ्लो लाइट काफी दिलचस्प लगता है क्या यह मुफ़्त है? और अगर आप इसका एक कार्यशील उदाहरण प्रदान कर सकते हैं तो मैं इसकी सराहना करूँगा! धन्यवाद
R.Coder

वैसे शानदार जवाब!
आर। कोडर

यह निःशुल्क है। एक कार्यशील उदाहरण के लिए इसे जांचें । हम बहुत अधिक सटीकता के साथ नेटवर्क कनेक्शन का उपयोग किए बिना 225 लोगों के चेहरे की पहचान करने में सक्षम थे, हालांकि उपयोगकर्ता अनुभव पक्ष में कुछ गड़बड़ थे। लेकिन यह एक अच्छा किक ऑफ होना चाहिए।
फ़रज़ाद वर्टिगो

ठीक है, मैं इसे एक कोशिश दे दूँगा
R.Coder

1
इसने काम कर दिया!!!! मैंने अंततः उस नेट मॉडल के टैफलाइट को निकाला और एक प्रशिक्षित छवि पर 80% से अधिक सटीकता प्राप्त की। लेकिन समय जटिलता वास्तव में बहुत बड़ी है !!, दो छवियों की तुलना करने के लिए इसे कम करने के लिए किसी भी विचार पर न्यूनतम 5 से 6 सेकंड लगते हैं?
आर। कोडर

2

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


क्या आपके पास ऐसा करने के लिए कोई उदाहरण है?
आर। कोडर

हां, मैं एक स्थिर छवि पर चेहरा पहचान कर रहा हूं
R.Coder

उपयोग करने के तरीके के उदाहरण के लिए यहाँ देखें train(): docs.opencv.org/3.4/dd/d65/…
फ्लोरियन एच्क्लेटर

यह उत्तर मदद नहीं करता है यदि आप एंड्रॉइड से संबंधित कुछ कोडित उदाहरण प्रदान कर सकते हैं तो यह बेहतर होगा!
आर। कोडर

0

1) LBPHrecognizer -> LBPHFaceRecognizer (1, 8, 8, 8, 100) को प्रारंभ करते समय थ्रेसहोल्ड मान बदलें।

2) प्रत्येक चेहरे को कम से कम 2-3 चित्रों के साथ प्रशिक्षित करें क्योंकि ये पहचानकर्ता मुख्य रूप से तुलना पर काम करते हैं

3) पहचानते समय सटीकता सीमा निर्धारित करें। कुछ इस तरह से करें:

//predicting result
// LoadData is a static class that contains trained recognizer
// _result is the gray frame image captured by the camera
LBPHFaceRecognizer.PredictionResult ER = LoadData.recog.Predict(_result);
int temp_result = ER.Label;

imageBox1.SizeMode = PictureBoxSizeMode.StretchImage;
imageBox1.Image = _result.Mat;

//Displaying predicted result on screen
// LBPH returns -1 if face is recognized
if ((temp_result != -1) && (ER.Distance < 55)){  
     //I get best accuracy at 55, you should try different values to determine best results
     // Do something with detected image
}

क्या आप मेरे वर्तमान कोड को संपादित कर सकते हैं और जावा में ऐसा करने के लिए एक कार्यशील उदाहरण प्रदान कर सकते हैं?
आर। कोडर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.