OPENCV+JAVA實(shí)現(xiàn)人臉識(shí)別
本文實(shí)例為大家分享了JAVA實(shí)現(xiàn)人臉識(shí)別的具體代碼,供大家參考,具體內(nèi)容如下
官方下載 安裝文件 ,以win7為例,下載opencv-2.4.13.3-vc14.exe
安裝后,在build目錄下 D:\opencv\build\java,獲取opencv-2413.jar,copy至項(xiàng)目目錄
同時(shí)需要dll文件 與 各 識(shí)別xml文件,進(jìn)行不同特征的識(shí)別(人臉,側(cè)臉,眼睛等)
dll目錄:D:\opencv\build\java\x64\opencv_java2413.dll
xml目錄:D:\opencv\sources\data\haarcascades\haarcascade_frontalface_alt.xml(目錄中有各類(lèi)識(shí)別文件)
項(xiàng)目結(jié)構(gòu):
具體代碼:由于需要用到 opencv 的dll文件,故要么放在java library path 中,或放在jre lib 中,windows下可放在System32目錄下,也可以在代碼中動(dòng)態(tài)加載,如下:
package opencv; import com.sun.scenario.effect.ImageData; import org.opencv.core.*; import org.opencv.core.Point; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; import org.opencv.objdetect.CascadeClassifier; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Vector; /** * Created by Administrator on 2017/8/17. */ public class Test { static{ // 導(dǎo)入opencv的庫(kù) String opencvpath = System.getProperty("user.dir") + "\\opencv\\x64\\"; String libPath = System.getProperty("java.library.path"); String a = opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll"; System.load(opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll"); } public static String getCutPath(String filePath){ String[] splitPath = filePath.split("\\."); return splitPath[0]+"Cut"+"."+splitPath[1]; } public static void process(String original,String target) throws Exception { String originalCut = getCutPath(original); String targetCut = getCutPath(target); if(detectFace(original,originalCut) && detectFace(target,targetCut)){ } } public static boolean detectFace(String imagePath,String outFile) throws Exception { System.out.println("\nRunning DetectFaceDemo"); // 從配置文件lbpcascade_frontalface.xml中創(chuàng)建一個(gè)人臉識(shí)別器,該文件位于opencv安裝目錄中 CascadeClassifier faceDetector = new CascadeClassifier( "C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_frontalface_alt.xml"); Mat image = Highgui.imread(imagePath); // 在圖片中檢測(cè)人臉 MatOfRect faceDetections = new MatOfRect(); faceDetector.detectMultiScale(image, faceDetections); System.out.println(String.format("Detected %s faces", faceDetections.toArray().length)); Rect[] rects = faceDetections.toArray(); if(rects != null && rects.length > 1){ throw new RuntimeException("超過(guò)一個(gè)臉"); } // 在每一個(gè)識(shí)別出來(lái)的人臉周?chē)?huà)出一個(gè)方框 Rect rect = rects[0]; Core.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(rect); Mat mat = new Mat(); Size size = new Size(300, 300); Imgproc.resize(sub, mat, size);//將人臉進(jìn)行截圖并保存 return Highgui.imwrite(outFile, mat); // 將結(jié)果保存到文件 // String filename = "C:\\Users\\Administrator\\Desktop\\opencv\\faceDetection.png"; // System.out.println(String.format("Writing %s", filename)); // Highgui.imwrite(filename, image); } public static void setAlpha(String imagePath,String outFile) { /** * 增加測(cè)試項(xiàng) * 讀取圖片,繪制成半透明 */ try { ImageIcon imageIcon = new ImageIcon(imagePath); BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(),imageIcon.getIconHeight() , BufferedImage.TYPE_4BYTE_ABGR); Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics(); g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver()); //循環(huán)每一個(gè)像素點(diǎn),改變像素點(diǎn)的Alpha值 int alpha = 100; for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) { for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) { int rgb = bufferedImage.getRGB(j2, j1); rgb = ( (alpha + 1) << 24) | (rgb & 0x00ffffff); bufferedImage.setRGB(j2, j1, rgb); } } g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver()); //生成圖片為PNG ImageIO.write(bufferedImage, "png", new File(outFile)); } catch (Exception e) { e.printStackTrace(); } } private static void watermark(String a,String b,String outFile, float alpha) throws IOException { // 獲取底圖 BufferedImage buffImg = ImageIO.read(new File(a)); // 獲取層圖 BufferedImage waterImg = ImageIO.read(new File(b)); // 創(chuàng)建Graphics2D對(duì)象,用在底圖對(duì)象上繪圖 Graphics2D g2d = buffImg.createGraphics(); int waterImgWidth = waterImg.getWidth();// 獲取層圖的寬度 int waterImgHeight = waterImg.getHeight();// 獲取層圖的高度 // 在圖形和圖像中實(shí)現(xiàn)混合和透明效果 g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); // 繪制 g2d.drawImage(waterImg, 0, 0, waterImgWidth, waterImgHeight, null); g2d.dispose();// 釋放圖形上下文使用的系統(tǒng)資源 //生成圖片為PNG ImageIO.write(buffImg, "png", new File(outFile)); } public static boolean mergeSimple(BufferedImage image1, BufferedImage image2, int posw, int posh, File fileOutput) { //合并兩個(gè)圖像 int w1 = image1.getWidth(); int h1 = image1.getHeight(); int w2 = image2.getWidth(); int h2 = image2.getHeight(); BufferedImage imageSaved = new BufferedImage(w1, h1, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = imageSaved.createGraphics(); // 增加下面代碼使得背景透明 g2d.drawImage(image1, null, 0, 0); image1 = g2d.getDeviceConfiguration().createCompatibleImage(w1, w2, Transparency.TRANSLUCENT); g2d.dispose(); g2d = image1.createGraphics(); // 背景透明代碼結(jié)束 // for (int i = 0; i < w2; i++) { // for (int j = 0; j < h2; j++) { // int rgb1 = image1.getRGB(i + posw, j + posh); // int rgb2 = image2.getRGB(i, j); // // if (rgb1 != rgb2) { // //rgb2 = rgb1 & rgb2; // } // imageSaved.setRGB(i + posw, j + posh, rgb2); // } // } boolean b = false; try { b = ImageIO.write(imageSaved, "png", fileOutput); } catch (IOException ie) { ie.printStackTrace(); } return b; } public static void main(String[] args) throws Exception { String a,b,c,d; a = "C:\\Users\\Administrator\\Desktop\\opencv\\zzl.jpg"; d = "C:\\Users\\Administrator\\Desktop\\opencv\\cgx.jpg"; //process(a,d); a = "C:\\Users\\Administrator\\Desktop\\opencv\\zzlCut.jpg"; d = "C:\\Users\\Administrator\\Desktop\\opencv\\cgxCut.jpg"; CascadeClassifier faceDetector = new CascadeClassifier( "C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_frontalface_alt.xml"); CascadeClassifier eyeDetector1 = new CascadeClassifier( "C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_eye.xml"); CascadeClassifier eyeDetector2 = new CascadeClassifier( "C:\\Users\\Administrator\\Desktop\\opencv\\haarcascade_eye_tree_eyeglasses.xml"); Mat image = Highgui.imread("C:\\Users\\Administrator\\Desktop\\opencv\\gakki.jpg"); // 在圖片中檢測(cè)人臉 MatOfRect faceDetections = new MatOfRect(); //eyeDetector2.detectMultiScale(image, faceDetections); Vector<Rect> objects; eyeDetector1.detectMultiScale(image, faceDetections, 2.0,1,1,new Size(20,20),new Size(20,20)); Rect[] rects = faceDetections.toArray(); Rect eyea,eyeb; eyea = rects[0];eyeb = rects[1]; System.out.println("a-中心坐標(biāo) " + eyea.x + " and " + eyea.y); System.out.println("b-中心坐標(biāo) " + eyeb.x + " and " + eyeb.y); //獲取兩個(gè)人眼的角度 double dy=(eyeb.y-eyea.y); double dx=(eyeb.x-eyea.x); double len=Math.sqrt(dx*dx+dy*dy); System.out.println("dx is "+dx); System.out.println("dy is "+dy); System.out.println("len is "+len); double angle=Math.atan2(Math.abs(dy),Math.abs(dx))*180.0/Math.PI; System.out.println("angle is "+angle); for(Rect rect:faceDetections.toArray()) { Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0)); } String filename = "C:\\Users\\Administrator\\Desktop\\opencv\\ouput.png"; System.out.println(String.format("Writing %s", filename)); Highgui.imwrite(filename, image); // watermark(a,d,"C:\\Users\\Administrator\\Desktop\\opencv\\zzlTm2.jpg",0.7f); // // // 讀取圖像,不改變圖像的原始信息 // Mat image1 = Highgui.imread(a); // Mat image2 = Highgui.imread(d); // Mat mat1 = new Mat();Mat mat2 = new Mat(); // Size size = new Size(300, 300); // Imgproc.resize(image1, mat1, size); // Imgproc.resize(image2, mat2, size); // Mat mat3 = new Mat(size,CvType.CV_64F); // //Core.addWeighted(mat1, 0.5, mat2, 1, 0, mat3); // // //Highgui.imwrite("C:\\Users\\Administrator\\Desktop\\opencv\\add.jpg", mat3); // // mergeSimple(ImageIO.read(new File(a)), // ImageIO.read(new File(d)),0,0, // new File("C:\\Users\\Administrator\\Desktop\\opencv\\add.jpg")); } }
最終效果:人臉旁有綠色邊框,可以將綠色邊框圖片截取,生成人臉圖
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
為何HashSet中使用PRESENT而不是null作為value
這篇文章主要介紹了為何HashSet中使用PRESENT而不是null作為value,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10Java實(shí)現(xiàn)的二叉樹(shù)常用操作【前序建樹(shù),前中后遞歸非遞歸遍歷及層序遍歷】
這篇文章主要介紹了Java實(shí)現(xiàn)的二叉樹(shù)常用操作,包括二叉樹(shù)的前序建樹(shù),前中后遞歸非遞歸遍歷及層序遍歷等相關(guān)操作技巧,需要的朋友可以參考下2018-01-01SpringBoot配置Profile實(shí)現(xiàn)多環(huán)境支持
這篇文章主要介紹了SpringBoot配置Profile實(shí)現(xiàn)多環(huán)境支持操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08spring?boot整合mongo查詢(xún)converter異常排查記錄
這篇文章主要為大家介紹了spring?boot整合mongo查詢(xún)時(shí)拋出converter異常的排查解決記錄,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-03-03java獲取request中的參數(shù)以及java解析URL問(wèn)號(hào)后的參數(shù)
這篇文章主要介紹了java獲取request中的參數(shù)以及java解析URL問(wèn)號(hào)后的參數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12Java靜態(tài)代理和動(dòng)態(tài)代理總結(jié)
這篇文章主要介紹了Java靜態(tài)代理和動(dòng)態(tài)代理總結(jié),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02java中的FileInputStream三種read()函數(shù)用法
這篇文章主要介紹了java中的FileInputStream三種read()函數(shù)用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12