Opencv java實現人臉摳圖和行爲識別


基於java的OpenCV環境搭建(Windows平臺上ecplise) https://blog.csdn.net/qq_32447301/article/details/78494913


https://download.csdn.net/download/qq_37996327/10504398  opencv下載地址 親測可用 





以下爲java測試案例代碼



package com.snail.util.opencv;




import java.io.File;
import java.util.ArrayList;


import org.apache.ibatis.migration.MigrationException;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;


public class DetectImage {
// 學習SVM
public static  String StudyXML = "E:\\opencv\\build\\x64\\vc14\\bin\\studyxml\\cascade.xml";
// 睡覺SVM
public static  String SleepXML = "E:\\opencv\\build\\x64\\vc14\\bin\\xml\\cascade.xml";
// 玩手機SVM
public static  String MobleXML = "E:\\opencv\\build\\x64\\vc14\\bin\\xml\\cascade.xml";
// 抽菸SVM haarcascade_upperbody.xml
public static  String SmokeXML = "E:\\opencv\\sources\\data\\haarcascades\\haarcascade_upperbody.xml";
static{
// 載入opencv的庫
System.out.println("加載opencv.dll庫文件");
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
/**
* 
* @param path  文件路徑
* @param savePath  保存地址 
* @param length  文件下的文件數量
* @param xmlPath xml的路徑
*/
public static void detect(String path,String savePath,int length,String xmlPath){
System.out.println("Running DetectFace ... ");


// 從配置文件lbpcascade_frontalface.xml中創建一個人臉識別器,該文件位於opencv安裝目錄中
CascadeClassifier faceDetector = new CascadeClassifier(xmlPath);
CascadeClassifier face = new CascadeClassifier("E:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml");
//faceDetector.load();
Mat image = Imgcodecs.imread(path);


// 在圖片中檢測人臉
MatOfRect faceDetections = new MatOfRect();
//faceDetections.
//faceDetector.detectMultiScale(image, faceDetections);
faceDetector.detectMultiScale(image, faceDetections);
//faceDetector.
System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));


Rect[] rects = faceDetections.toArray();


//System.out.println("人臉檢測完畢!畫出矩形...");  


for(int i = 0 ; i < rects.length ; i++){


Rect rect = rects[i];
Mat sub = image.submat(rect);   //Mat sub = new Mat(image,rect);
Mat mat = new Mat();
Size size = new Size(300, 300);
Imgproc.resize(sub, mat, size);//將人臉進行截圖並保存 
//String outFile = savepath;
//截圖
//Imgcodecs.imwrite("E:/image/conation"+"//"+length+".jpg", mat);
Imgcodecs.imwrite(savePath+"//"+length+".jpg", mat);
//Mat facemat = Imgcodecs.imread(savePath+"//"+length+".jpg");
//MatOfRect faceRect = new MatOfRect();


/*face.detectMultiScale(facemat, faceRect);
if(faceRect.toArray().length > 0){


}else{
File file = new File(savePath+"//"+length+".jpg");
file.delete();
}*/
++length;
}


}

public static void main(String[] args) throws Exception {
ArrayList<File> file = CutOpencvFace.getFiles("E:\\ftp\\10.4.1.55");  //源文件
for(File files:file){
ArrayList<File> filess = CutOpencvFace.getFiles("E:\\image\\behavior");  //保存路徑
detect(files.getPath(), "E:\\image\\behavior", filess.size(), SmokeXML);;
}
}



}





//人臉摳圖



package com.snail.util.opencv;




import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;


import java.io.File;
import java.util.ArrayList;


public class CutOpencvFace {




static{
// 載入opencv的庫
System.out.println("加載opencv.dll庫文件");
//String opencvpath = System.getProperty("user.dir") + "\\opencv\\x64\\";
//String opencvpath = "E:\\opencv\build\\java\\x64\\";
//String opencvDllName = opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll";
//System.load(opencvDllName);
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}






public static  void detectFace(String imagePath,String savepath) throws Exception
{


System.out.println("Running DetectFace ... ");


// 從配置文件lbpcascade_frontalface.xml中創建一個人臉識別器,該文件位於opencv安裝目錄中
CascadeClassifier faceDetector = new CascadeClassifier("E:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml");
//faceDetector.load();
Mat image = Imgcodecs.imread(imagePath);


// 在圖片中檢測人臉
MatOfRect faceDetections = new MatOfRect();
//faceDetections.
//faceDetector.detectMultiScale(image, faceDetections);
faceDetector.detectMultiScale(image, faceDetections);
//faceDetector.
System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));


Rect[] rects = faceDetections.toArray();
/*if(rects != null && rects.length > 1){
            throw new RuntimeException("超過一個臉");
        }*/
// 在每一個識別出來的人臉周圍畫出一個方框


System.out.println("人臉檢測完畢!畫出矩形...");  
ArrayList<File> fileList = getFiles(savepath);
Integer length = fileList.size();
for(int i = 0 ; i < rects.length ; i++){
Rect rect = rects[i];


//畫框
/*Imgproc.rectangle(image, new Point(rect.x-2, rect.y-2),
new Point(rect.x + rect.width, rect.y + rect.height),
new Scalar(0, 255, 0));*/
//截圖
Mat sub = image.submat(rects[i]);   //Mat sub = new Mat(image,rect);
Mat mat = new Mat();
Size size = new Size(300, 300);
Imgproc.resize(sub, mat, size);//將人臉進行截圖並保存 
//String outFile = savepath;
//零時存放
Imgcodecs.imwrite(savepath+"\\"+length+".jpg", mat);
for(int k = 0 ; k < fileList.size() ;k++){
Integer baifen =  ComplateFacePixel.compareImage(savepath+"\\"+length+".jpg", fileList.get(k).getPath());
if(baifen >=30){
File file = new File(savepath+"\\"+length+".jpg");
file.delete();
break ;
}else if(k==length-1){
++length;
break;
}
}


}
//比較圖片之間的像素
/*for(int k = 0 ; k < fileList.size(); k++){
File file  = fileList.get(k);
try{
Integer max = ComplateFacePixel.compareImage(file.getPath(), outFile+"\\faceCut"+fileList.size()+".jpg");
if(max>20){
File filesa = new File(outFile+"\\faceCut"+fileList.size()+".jpg");
filesa.delete();
System.out.println("截圖重複 ,已刪除");
break ;
}else if(max<20){


}else if(k == fileList.size()-1){
//最後一張 小於30保存
//Imgcodecs.imwrite(outFile+"\\faceCut"+i+".jpg", mat);
System.out.println(String.format("圖片裁切成功,裁切後圖片文件爲: %s", outFile));
}
}catch(NullPointerException e){
//Imgcodecs.imwrite(outFile+"\\faceCut"+i+".jpg", mat);
break ; 
}
}
if(fileList.size() == 0){
Imgcodecs.imwrite(outFile+"\\faceCut"+i+".jpg", mat);
System.out.println(String.format("圖片裁切成功,裁切後圖片文件爲: %s", outFile));
}


}
String outFile=savepath+"\\detectFace.jpg";
Imgcodecs.imwrite(outFile, image);
System.out.println(String.format("人臉識別成功,人臉圖片文件爲: %s", outFile));*/




}
public static  ArrayList<File> getFiles(String path) throws Exception {
//目標集合fileList
ArrayList<File> fileList = new ArrayList<File>();
File file = new File(path);
if(file.isDirectory()){
File []files = file.listFiles();
for(File fileIndex:files){
//如果這個文件是目錄,則進行遞歸搜索
if(fileIndex.isDirectory()){
getFiles(fileIndex.getPath());
}else {
//如果文件是普通文件,則將文件句柄放入集合中
fileList.add(fileIndex);
}
}
}
return fileList;
}


public static  ArrayList<String> getFilesPath(String path) throws Exception {
//目標集合fileList
ArrayList<String> fileList = new ArrayList<String>();
File file = new File(path);
if(file.isDirectory()){
File []files = file.listFiles();
for(File fileIndex:files){
//如果這個文件是目錄,則進行遞歸搜索
fileList.add(fileIndex.getPath());
}
}
return fileList;
}




}





package com.snail.util.opencv;


import java.awt.image.BufferedImage;
import java.io.File;
import java.util.List;


import javax.imageio.ImageIO;


import org.opencv.core.Core;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.core.CvType;
import org.opencv.core.DMatch;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDMatch;
import org.opencv.core.MatOfKeyPoint;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.features2d.DescriptorExtractor;
import org.opencv.features2d.DescriptorMatcher;
import org.opencv.features2d.FeatureDetector;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;


public class ComplateFacePixel {


public static String[][] getPX(String args) {  
int[] rgb = new int[3];  


File file = new File(args);  
BufferedImage bi = null;  
try {  
bi = ImageIO.read(file);  
} catch (Exception e) {  
e.printStackTrace();  
}  


int width = bi.getWidth();  
int height = bi.getHeight();  
int minx = bi.getMinX();  
int miny = bi.getMinY();  
String[][] list = new String[width][height];  
for (int i = minx; i < width; i++) {  
for (int j = miny; j < height; j++) {  
int pixel = bi.getRGB(i, j);  
rgb[0] = (pixel & 0xff0000) >> 16;  
rgb[1] = (pixel & 0xff00) >> 8;  
rgb[2] = (pixel & 0xff);  
list[i][j] = rgb[0] + "," + rgb[1] + "," + rgb[2];  


}  
}  
return list;  


}  


public static Integer compareImage(String imgPath1, String imgPath2){  




String[] images = {imgPath1, imgPath2};  
if (images.length == 0) {  
System.out.println("Usage >java BMPLoader ImageFile.bmp");  
System.exit(0);  
}  


// 分析圖片相似度 begin  
String[][] list1 = getPX(images[0]);  
String[][] list2 = getPX(images[1]);  
int xiangsi = 0;  
int busi = 0;  
int i = 0, j = 0;  
for (String[] strings : list1) {  
if ((i + 1) == list1.length) {  
continue;  
}  
for (int m=0; m<strings.length; m++) {  
try {  
String[] value1 = list1[i][j].toString().split(",");  
String[] value2 = list2[i][j].toString().split(",");  
int k = 0;  
for (int n=0; n<value2.length; n++) {  
if (Math.abs(Integer.parseInt(value1[k]) - Integer.parseInt(value2[k])) < 5) {  
xiangsi++;  
} else {  
busi++;  
}  
}  
} catch (RuntimeException e) {  
continue;  
}  
j++;  
}  
i++;  
}  


list1 = getPX(images[1]);  
list2 = getPX(images[0]);  
i = 0;  
j = 0;  
for (String[] strings : list1) {  
if ((i + 1) == list1.length) {  
continue;  
}  
for (int m=0; m<strings.length; m++) {  
try {  
String[] value1 = list1[i][j].toString().split(",");  
String[] value2 = list2[i][j].toString().split(",");  
int k = 0;  
for (int n=0; n<value2.length; n++) {  
if (Math.abs(Integer.parseInt(value1[k]) - Integer.parseInt(value2[k])) < 5) {  
xiangsi++;  
} else {  
busi++;  
}  
}  
} catch (RuntimeException e) {  
continue;  
}  
j++;  
}  
i++;  
}  
String baifen = "";  
try {  
baifen = ((Double.parseDouble(xiangsi + "") / Double.parseDouble((busi + xiangsi) + "")) + "");  
baifen = baifen.substring(baifen.indexOf(".") + 1, baifen.indexOf(".") + 3);  
} catch (Exception e) {  
baifen = "0";  
}  
if (baifen.length() <= 0) {  
baifen = "0";  
}  
if(busi == 0){  
baifen="100";  
}  
System.out.println( " 相似率:" + Integer.parseInt(baifen) + "%");  
return Integer.parseInt(baifen);


}  


@SuppressWarnings("deprecation")
public static void imgMatching2(String path,String path2) throws Exception {  
        //System.loadLibrary(Core.NATIVE_LIBRARY_NAME);  
        Mat src_base = Imgcodecs.imread(path);  
        Mat src_test = Imgcodecs.imread(path2);  
        Mat gray_base = new Mat();  
        Mat gray_test = new Mat();  
        // 轉換爲灰度  
        //Imgproc.cvtColor(src_base, gray_base, Imgproc.COLOR_RGB2GRAY);  
        //Imgproc.cvtColor(src_test, gray_test, Imgproc.COLOR_RGB2GRAY);  
        
        // 初始化ORB檢測描述子  
FeatureDetector featureDetector = FeatureDetector.create(FeatureDetector.ORB);//特別提示下這裏opencv暫時不支持SIFT、SURF檢測方法,這個好像是opencv(windows) java版的一個bug,本人在這裏被坑了好久。  
        //@SuppressWarnings("deprecation")
DescriptorExtractor descriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.ORB);  
        // 關鍵點及特徵描述矩陣聲明  
        MatOfKeyPoint keyPoint1 = new MatOfKeyPoint(), keyPoint2 = new MatOfKeyPoint();  
        Mat descriptorMat1 = new Mat(), descriptorMat2 = new Mat();  
        // 計算ORB特徵關鍵點  
        featureDetector.detect(gray_base, keyPoint1);  
        featureDetector.detect(gray_test, keyPoint2);  
        // 計算ORB特徵描述矩陣  
        descriptorExtractor.compute(gray_base, keyPoint1, descriptorMat1);  
        descriptorExtractor.compute(gray_test, keyPoint2, descriptorMat2);  
        float result = 0;  
        // 特徵點匹配  
        System.out.println("test5:" + keyPoint1.size());  
        System.out.println("test3:" + keyPoint2.size());  
        if (!keyPoint1.size().empty() && !keyPoint2.size().empty()) {  
            // FlannBasedMatcher matcher = new FlannBasedMatcher();  
            DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_L1);  
            MatOfDMatch matches = new MatOfDMatch();  
            matcher.match(descriptorMat1, descriptorMat2, matches);  
            // 最優匹配判斷  
            double minDist = 100;  
            DMatch[] dMatchs = matches.toArray();  
            int num = 0;  
            for (int i = 0; i < dMatchs.length; i++) {  
                if (dMatchs[i].distance <= 2 * minDist) {  
                    result += dMatchs[i].distance * dMatchs[i].distance;  
                    num++;  
                }  
            }  
            // 匹配度計算  
            result /= num;  
        }  
        System.out.println(result);  
    }  

public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
try {
List<String> list = CutOpencvFace.getFilesPath("E:\\image\\face");
int i = 0; 
for(String str : list){
System.out.println(str);
System.out.println(i++);
ComplateFacePixel.compareImage(str,"E:\\image\\face\\30.jpg");
}

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//complare1("E:/mage/photo/cut/faceCut20.jpg","E:/mage/photo/cut/faceCut21.jpg");
}




}















歡迎掃碼:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章