package it.acxent.face.fr; import it.acxent.common.StatusMsg; import it.acxent.db.ApplParmFull; import it.acxent.db.DBAdapter; import it.acxent.db.ResParm; import it.acxent.db.WcString; import it.acxent.face.api.opencv.FaceRecognition; import it.acxent.face.api.opencv.TrainingImage; import it.acxent.util.Timer; import it.acxent.util.Vectumerator; import java.io.File; import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantLock; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.MatOfInt; import org.opencv.face.EigenFaceRecognizer; import org.opencv.face.FisherFaceRecognizer; import org.opencv.face.LBPHFaceRecognizer; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; public class FaceRecognizer extends it.acxent.dm.FaceRecognizer implements Serializable { class ThreadCaricaModelli extends Thread { private FaceRecognizerCR CR; private boolean useFile = false; public ThreadCaricaModelli(FaceRecognizerCR l_CR, boolean l_usaFile) { this.CR = l_CR; this.useFile = l_usaFile; if (!FaceRecognizer.threadCaricaModelli) { FaceRecognizer.threadCaricaModelli = true; start(); } } public void run() { boolean debug = true; String TAG_THREAD_MSG = " CACHE MODELS "; Timer timerTotal = new Timer(); Timer timer = new Timer(); if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + " CACHE MODELS FaceRecognition.getInstance "); FaceRecognition.getInstance(FaceRecognizer.this.getApFull()); timerTotal.start(); Vectumerator vec = FaceRecognizer.this.findByCR(this.CR, 0, 0); int i = 0; while (vec.hasMoreElements()) { i++; FaceRecognizer row = (FaceRecognizer)vec.nextElement(); if (this.useFile) { if (row.isModelFileExist(0L)) { timer.start(); if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + " CACHE MODELS Recognizer modelli files " + String.valueOf(DBAdapter.getNow()) + " ...." + row.getCodice()); StatusMsg.updateMsgByTag(FaceRecognizer.this.getApFull(), " CACHE MODELS ", " Recognizer " + row.getCodice() + " ...." + String.valueOf(timer.getTStart())); row.precaricaModelliFiles(); timer.stop(); if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + " CACHE MODELS Recognizer modelli files " + String.valueOf(DBAdapter.getNow()) + " ...." + row.getCodice()); continue; } if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + " CACHE MODELS Recognizer modelli files " + String.valueOf(DBAdapter.getNow()) + " FILE NON TROVATO: " + row.getCodice()); continue; } if (row.getFlgDisabilita() == 0L) { timer.start(); if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + " CACHE MODELS Recognizer by training " + String.valueOf(DBAdapter.getNow()) + " ...." + row.getCodice()); StatusMsg.updateMsgByTag(FaceRecognizer.this.getApFull(), " CACHE MODELS ", " Recognizer " + row.getCodice() + " ...." + String.valueOf(timer.getTStart())); row.precaricaModelli(); timer.stop(); if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + " CACHE MODELS Recognizer by training " + String.valueOf(DBAdapter.getNow()) + " ...." + row.getCodice()); } } timerTotal.stop(); StatusMsg.updateMsgByTag(FaceRecognizer.this.getApFull(), " CACHE MODELS ", "FINE: " + timerTotal.getDurata()); if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + " CACHE MODELS FINE: " + String.valueOf(DBAdapter.getNow())); DBAdapter.sleepInSecond(4); StatusMsg.deleteMsgByTag(FaceRecognizer.this.getApFull(), " CACHE MODELS "); FaceRecognizer.threadCaricaModelli = false; } } private boolean debug = false; private static final long serialVersionUID = 1701089773600L; private long id_users; private Users users; private org.opencv.face.FaceRecognizer ocvFrLBPH; private org.opencv.face.FaceRecognizer ocvFrEigen; private org.opencv.face.FaceRecognizer ocvFrFish; public static boolean threadCaricaModelli = false; private long nTrainingImagesMax; private long flgTrainingMode; private long flgDisabilita; private static final ConcurrentHashMap recognizerCache = new ConcurrentHashMap<>(); private static final ReentrantLock trainingLock = new ReentrantLock(); public static final String TAG_TRAINING_RUN = "TRAINING_RUN"; public FaceRecognizer(ApplParmFull newApplParmFull) { super(newApplParmFull); } public FaceRecognizer() {} public static synchronized ResParm addNTrainingImages(FaceRecognizer bean, long newNTrainingImages) { bean.setNTrainingImages(bean.getNTrainingImages() + newNTrainingImages); return bean.save(); } protected ResParm checkDeleteCascade() { return new ResParm(true); } protected void deleteCascade() {} public Vectumerator findByCR(FaceRecognizerCR CR, int pageNumber, int pageRows) { String s_Sql_Find = "select A.* from FACE_RECOGNIZER AS A"; String s_Sql_Order = " order by A.descrizione"; WcString wc = new WcString(); if (CR.getId_faceRecognizer() > 0L) wc.addWc("A.id_faceRecognizer=" + CR.getId_faceRecognizer()); try { PreparedStatement stmt = getConn().prepareStatement(s_Sql_Find + s_Sql_Find + wc.toString()); return findRows(stmt, pageNumber, pageRows); } catch (SQLException e) { removeCPConnection(); handleDebug(e); return AB_EMPTY_VECTUMERATOR; } } public void findByCode(String l_code) { String s_Sql_Find = "select A.* from FACE_RECOGNIZER AS A"; String s_Sql_Order = ""; WcString wc = new WcString(); wc.addWc("A.codice='" + l_code + "'"); try { PreparedStatement stmt = getConn().prepareStatement(s_Sql_Find + s_Sql_Find + wc.toString()); findFirstRecord(stmt); } catch (SQLException e) { removeCPConnection(); handleDebug(e); } } public void findByFaceRecognizer(long l_id_faceRecognizer) { String s_Sql_Find = "select A.* from FACE_FACE_RECOGNIZER AS A"; String s_Sql_Order = ""; WcString wc = new WcString(); wc.addWc("A.id_faceRecognizer=" + l_id_faceRecognizer); try { PreparedStatement stmt = getConn().prepareStatement(s_Sql_Find + s_Sql_Find + wc.toString()); findFirstRecord(stmt); } catch (SQLException e) { removeCPConnection(); handleDebug(e); } } public boolean isModelFileExist(long recognizerType) { String fullFileName = getFullFileName(recognizerType); return new File(fullFileName).exists(); } @Deprecated public org.opencv.face.FaceRecognizer getOcvFaceRecognizerWithLoadedModelOriginal(long recognizerType) { String fullFileName = getFullFileName(recognizerType); String cacheKey = "" + recognizerType + ":" + recognizerType; if (recognizerCache.containsKey(cacheKey)) return recognizerCache.get(cacheKey); return null; } public org.opencv.face.FaceRecognizer getOcvFaceRecognizerWithLoadedModel(long recognizerType) { boolean debug = false; String fullFileName = getFullFileName(recognizerType); String cacheKey = "" + recognizerType + ":" + recognizerType; if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModel key: " + cacheKey); if (debug) { DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModel elenco chiavi presenti!!"); for (String key : recognizerCache.keySet()) System.out.println("Key: " + key); } if (recognizerCache.containsKey(cacheKey)) { DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModel key: " + cacheKey + " TROVATO!!!!"); return recognizerCache.get(cacheKey); } trainingLock.lock(); try { if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModel key: " + cacheKey + " DENTRO IL LOCK!"); if (recognizerCache.containsKey(cacheKey)) { if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModel key: " + cacheKey + " TROVATO ALL'INTERNO DEL LOCK!!!!"); return recognizerCache.get(cacheKey); } DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModel prima di trainingAndCreateModel..."); trainingAndCreateModel(false); DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModel FATTO!!!"); if (recognizerCache.containsKey(cacheKey)) { if (debug) System.out.println( String.valueOf(DBAdapter.getNowTs()) + " getOcvFaceRecognizerWithLoadedModel key: " + String.valueOf(DBAdapter.getNowTs()) + " TROVATO DOPO IL TRAINING"); return recognizerCache.get(cacheKey); } if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModel key: " + cacheKey + " NON TROVATO DOPO IL TRAINING!!!!"); throw new IllegalStateException("Impossibile creare il modello per il tipo di recognizer: " + recognizerType); } finally { trainingLock.unlock(); if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModel key: " + cacheKey + " FUORI IL LOCK!"); } } public org.opencv.face.FaceRecognizer getOcvFaceRecognizerWithLoadedModelByFile(long recognizerType) { boolean debug = true; String fullFileName = getFullFileName(recognizerType); String cacheKey = "" + recognizerType + ":" + recognizerType; if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModelByFile key: " + cacheKey); if (debug) { DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModelByFile elenco chiavi presenti!!"); for (String key : recognizerCache.keySet()) System.out.println("Key: " + key); } if (recognizerCache.containsKey(cacheKey)) { if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModelByFile key: " + cacheKey + " TROVATO!!!!"); return recognizerCache.get(cacheKey); } if (!isModelFileExist(recognizerType)) { if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModelByFile key: " + cacheKey + " CACHE NON TROVATA E FILE MODELLO NON TROVATO! RITORNO NULL"); return null; } trainingLock.lock(); try { if (debug) System.out.println( String.valueOf(DBAdapter.getNowTs()) + " getOcvFaceRecognizerWithLoadedModelByFile key: " + String.valueOf(DBAdapter.getNowTs()) + " DENTRO IL LOCK!"); if (recognizerCache.containsKey(cacheKey)) { if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModelByFile key: " + cacheKey + " TROVATO ALL'INTERNO DEL LOCK!!!!"); return recognizerCache.get(cacheKey); } if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModelByFile prima di recognizer.read..."); org.opencv.face.FaceRecognizer recognizer = getOcvFaceRecognizerForModel(recognizerType); try { recognizer.read(fullFileName); recognizerCache.put(cacheKey, recognizer); } catch (Exception e) { System.out.println(String.valueOf(DBAdapter.getNowTs()) + " getOcvFaceRecognizerWithLoadedModelByFile prima di recognizer.read ECCEZIONE! " + String.valueOf(DBAdapter.getNowTs())); e.printStackTrace(); } if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModelByFile FATTO!!!"); if (recognizerCache.containsKey(cacheKey)) { if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModelByFile key: " + cacheKey + " TROVATO DOPO IL TRAINING"); return recognizerCache.get(cacheKey); } if (debug) DBAdapter.printDebug(debug, " getOcvFaceRecognizerWithLoadedModelByFile key: " + cacheKey + " NON TROVATO DOPO IL TRAINING!!!!"); throw new IllegalStateException("Impossibile creare il modello per il tipo di recognizer: " + recognizerType); } finally { trainingLock.unlock(); if (debug) System.out.println( String.valueOf(DBAdapter.getNowTs()) + " getOcvFaceRecognizerWithLoadedModelByFile key: " + String.valueOf(DBAdapter.getNowTs()) + " FUORI IL LOCK!"); } } public void removeOcvFaceRecognizerWithLoadedModel(long recognizerType) { String fullFileName = getFullFileName(recognizerType); String cacheKey = "" + recognizerType + ":" + recognizerType; if (recognizerCache.containsKey(cacheKey)) recognizerCache.remove(cacheKey); } public void removeAllOcvFaceRecognizerWithLoadedModel() { synchronized (recognizerCache) { recognizerCache.clear(); } } public void addOcvFaceRecognizerWithLoadedModel(long recognizerType, org.opencv.face.FaceRecognizer recognizer) { String fullFileName = getFullFileName(recognizerType); String cacheKey = "" + recognizerType + ":" + recognizerType; if (recognizerCache.containsKey(cacheKey)) recognizerCache.remove(cacheKey); DBAdapter.printDebug(this.debug, " addOcvFaceRecognizerWithLoadedModel key: " + cacheKey); recognizerCache.put(cacheKey, recognizer); } public void precaricaModelliFiles() { for (int i = 0; i < 1; i++) getOcvFaceRecognizerWithLoadedModelByFile((long)i); } public void precaricaModelli() { for (int i = 0; i < 1; i++) getOcvFaceRecognizerWithLoadedModel((long)i); } private org.opencv.face.FaceRecognizer getOcvFaceRecognizerForModel(long recognizerType) { if (recognizerType == 0L) return (org.opencv.face.FaceRecognizer)LBPHFaceRecognizer.create(); if (recognizerType == 2L) return (org.opencv.face.FaceRecognizer)EigenFaceRecognizer.create(); if (recognizerType == 1L) return (org.opencv.face.FaceRecognizer)FisherFaceRecognizer.create(); return null; } public long getId_users() { return this.id_users; } public Users getUsers() { this.users = (Users)getSecondaryObject((DBAdapter)this.users, Users.class, getId_users()); return this.users; } public void setId_users(long newId_users) { this.id_users = newId_users; setUsers(null); } public void setUsers(Users newUsers) { this.users = newUsers; } public String getFullFileName(long l_tipo) { return getPathRecognizer() + getPathRecognizer() + "_" + getTipo(l_tipo); } public String getFullFileNameBin(long l_tipo) { return getPathRecognizer() + getPathRecognizer() + "_" + getTipo(l_tipo) + ".dat"; } public String getPathRecognizer() { return getParm("path_img_base").getTesto() + "_recognizer/"; } public ResParm trainingAndCreateModel(boolean saveModel) { ResParm rp = new ResParm(); String TAG_THREAD_MSG = "TRAINING_RUN"; Timer timer = new Timer(); timer.start(); try { boolean debug = true; if (debug) System.out.println(String.valueOf(DBAdapter.getNowTs()) + " TRAINING_RUN trainingAndCreateModel FaceRecognition.getInstance "); FaceRecognition.getInstance(getApFull()); if (getId_faceRecognizer() == 0L) { if (debug) DBAdapter.printDebug(debug, " TRAINING_RUN trainingAndCreateModel NO getId_faceRecognizer "); rp.setStatus(false); rp.setMsg("Errore! FaceRecognizer nullo !!"); } else { StatusMsg.updateMsgByTag(getApFull(), "TRAINING_RUN", "START TRAINING FOR: " + getCodice()); if (debug) DBAdapter.printDebug(debug, " TRAINING_RUN START TRAINING FOR: " + getCodice()); int NUM_IMMAGINI_MAX = (int)getNTrainingImagesMax(); int totFotoElaborate = 0; FaceFaceRecognizer faceFR = new FaceFaceRecognizer(getApFull()); long totRecord = faceFR.getTotFaceByFaceRecognizer(getId_faceRecognizer()); if (debug) DBAdapter.printDebug(debug, " TRAINING_RUN totrecordfacebyfacerec: " + totRecord); int j = 0; List imageFilenames = new ArrayList<>(); Vectumerator vec = faceFR.findByFaceRecognizer(getId_faceRecognizer(), 1, NUM_IMMAGINI_MAX); while (vec.hasMoreElements()) { j++; FaceFaceRecognizer row = (FaceFaceRecognizer)vec.nextElement(); imageFilenames.add(new TrainingImage(row.getFace().getFullFileName(), (int)row.getId_faceLabel())); if (j % 10 == 0) StatusMsg.updateMsgByTag(getApFull(), "TRAINING_RUN", "(MAX: " + NUM_IMMAGINI_MAX + ") Preparing images for model: " + j + "/" + totRecord); } totFotoElaborate = j; StatusMsg.updateMsgByTag(getApFull(), "TRAINING_RUN", "Training create for " + totFotoElaborate + "/" + totRecord + " ... FR CODE: " + getCodice() + " .... "); if (debug) DBAdapter.printDebug(debug, " TRAINING_RUN trainingCreate --> trainingcreate"); rp = trainingCreate(imageFilenames, totFotoElaborate); File path = new File(getPathRecognizer()); if (!path.exists()) path.mkdirs(); for (int i = 0; i < 1; i++) { if (debug) DBAdapter.printDebug(debug, " TRAINING_RUN trainingAndCreateModel salvo modello: " + getFullFileName((long)i)); StatusMsg.updateMsgByTag(getApFull(), "TRAINING_RUN", "Saving " + getFullFileName((long)i) + " " + totFotoElaborate + "/" + totRecord + " ... FR CODE: " + getCodice() + " .... "); if (saveModel) { getOcvFaceRecognizer((long)i).save(getFullFileName((long)i)); } else { File theFile = new File(getFullFileName((long)i)); if (theFile.exists()) theFile.delete(); } if (debug) DBAdapter.printDebug(debug, " TRAINING_RUN trainingAndCreateModel metto in CACHE....: " + getFullFileName((long)i)); addOcvFaceRecognizerWithLoadedModel((long)i, getOcvFaceRecognizer((long)i)); } timer.stop(); setTsStart(timer.getTStart()); setTsStop(timer.getTStop()); setNTrainingImages((long)totFotoElaborate); rp.append(save()); } } catch (Exception e) { e.printStackTrace(); rp.setStatus(false); rp.setException(e); if (this.debug) DBAdapter.printDebug(this.debug, " TRAINING_RUN trainingAndCreateModel ECCEZIONE!!!! " + e.getMessage()); } if (this.debug) System.out.println( String.valueOf(DBAdapter.getNowTs()) + " TRAINING_RUN FINITO MODELLO " + String.valueOf(DBAdapter.getNowTs()) + " DURATA: " + getCodice()); StatusMsg.updateMsgByTag(getApFull(), "TRAINING_RUN", "FINITO MODELLO " + getCodice() + " DURATA: " + timer.getDurata()); DBAdapter.sleepInSecond(5); StatusMsg.deleteMsgByTag(getApFull(), "TRAINING_RUN"); return rp; } private ResParm trainingCreate(List trainingImages, int counter) { ResParm rp = new ResParm(); try { boolean debug = true; int j = 0; if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + "trainingCreate " + String.valueOf(DBAdapter.getNow()) + " immagini. counterStart: " + trainingImages.size()); if (trainingImages.size() > 0) { Mat labels = new Mat(trainingImages.size(), 1, CvType.CV_32SC1); MatOfInt labelsMat = new MatOfInt(); List trainingImagesMat = new ArrayList<>(); if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + "train: ciclo trainingImages. size: " + String.valueOf(DBAdapter.getNow())); for (TrainingImage trainingImage : trainingImages) { File imageFile = new File(trainingImage.getImageFileName()); Mat image = Imgcodecs.imread(imageFile.getAbsolutePath()); Mat grayImage = new Mat(); Imgproc.cvtColor(image, grayImage, 6); trainingImagesMat.add(grayImage); labels.put(j, 0, new double[] { (double)trainingImage.getLabel() }); j++; if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + " train: " + String.valueOf(DBAdapter.getNow()) + " count...:" + trainingImage.getImageFileName() + "/" + j + " label: " + counter); } labels.convertTo((Mat)labelsMat, CvType.CV_32SC1); for (int i = 0; i < 1; i++) { if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + " addestramento per modello n.: " + String.valueOf(DBAdapter.getNow()) + " ..."); getOcvFaceRecognizer((long)i).train(trainingImagesMat, labels); if (debug) System.out.println(String.valueOf(DBAdapter.getNow()) + " addestramento per modello n.: " + String.valueOf(DBAdapter.getNow()) + " FATTO!"); } } } catch (Exception e) { e.printStackTrace(); rp.setStatus(false); rp.setException(e); if (this.debug) System.out.println(String.valueOf(DBAdapter.getNow()) + " trainingCreate ECCEZIONE!!!! " + String.valueOf(DBAdapter.getNow())); } return rp; } public ResParm resetTraining() { FaceFaceRecognizer ffr = new FaceFaceRecognizer(getApFull()); return ffr.resetTrainingByFaceRecognizer(getId_faceRecognizer()); } private org.opencv.face.FaceRecognizer getOcvFaceRecognizer(long l_type) { if (l_type == 0L) { if (this.ocvFrLBPH == null) this.ocvFrLBPH = (org.opencv.face.FaceRecognizer)LBPHFaceRecognizer.create(); return this.ocvFrLBPH; } if (l_type == 2L) { if (this.ocvFrEigen == null) this.ocvFrEigen = (org.opencv.face.FaceRecognizer)EigenFaceRecognizer.create(); return this.ocvFrEigen; } if (l_type == 1L) { if (this.ocvFrFish == null) this.ocvFrFish = (org.opencv.face.FaceRecognizer)FisherFaceRecognizer.create(); return this.ocvFrFish; } return null; } public final ResParm startCaricaModelli(FaceRecognizerCR l_CR, boolean useFile) { if (!threadCaricaModelli) { new ThreadCaricaModelli(l_CR, useFile); return new ResParm(true, "Thread threadCaricaModelli avviato. usefile: " + useFile); } return new ResParm(false, "ATTENZIONE!! Thread in esecuzione!!!"); } public long getNTrainingImagesMax() { return (this.nTrainingImagesMax <= 0L) ? 10000L : this.nTrainingImagesMax; } public void setNTrainingImagesMax(long nTrainingImagesMax) { this.nTrainingImagesMax = nTrainingImagesMax; } public long getFlgTrainingMode() { return this.flgTrainingMode; } public void setFlgTrainingMode(long flgTrainingMode) { this.flgTrainingMode = flgTrainingMode; } public long getFlgDisabilita() { return this.flgDisabilita; } public void setFlgDisabilita(long flgDisabilita) { this.flgDisabilita = flgDisabilita; } }