All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.gdface.cassdk.FaceApiCas Maven / Gradle / Ivy

There is a newer version: 2.1.1
Show newest version
package net.gdface.cassdk;

import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;

import net.gdface.cassdk.jna.FaceAngle;
import net.gdface.cassdk.jna.THFI_FacePos;
import net.gdface.cassdk.jna.tagPOINT;
import net.gdface.cassdk.jna.tagRECT;
import net.gdface.image.ImageErrorException;
import net.gdface.image.LazyImage;
import net.gdface.image.UnsupportedFormatException;
import net.gdface.sdk.CodeInfo;
import net.gdface.sdk.EyeInfo;
import net.gdface.sdk.FAngle;
import net.gdface.sdk.FInt2;
import net.gdface.sdk.FRect;
import net.gdface.sdk.BaseFaceApiLocal;
import net.gdface.sdk.NotFaceDetectedException;
import net.gdface.sdk.RectUtils;
import net.gdface.utils.Assert;
import net.gdface.utils.FaceUtilitsX;

/**
 * CASSDK接口实现类
 * 
 * @author guyadong
 *
 */
public class FaceApiCas extends BaseFaceApiLocal {
	private static final Logger logger = Logger.getLogger(FaceApiCas.class.getSimpleName());
	private static final FaceApiCas INSTANCE = new FaceApiCas();
	static {
		if (!FaceUtilitsX.isBuilding()) {
			try {
				// CASSDK JNI接口静态区初始化
				Class.forName(net.gdface.cassdk.JniBridge.class.getName());
			} catch (ClassNotFoundException e) {
				logger.severe(e.getMessage());
				throw new ExceptionInInitializerError(e);
			}
		}
	}
	
	private FaceApiCas() {		
	}
	/**
	 * @return the instance
	 */
	public static FaceApiCas getInstance() {
		return INSTANCE;
	}

	@Override
	protected double doCompareCode(byte[] code1, byte[] code2) {
		return (double)JniBridge.compareFeature(code1, code2);
	}

	/**
	 * 底层类型->通用类型
	 * @param rect
	 * @return FRect,rect为{@code null}时返回{@code null}
	 */	
	static private FRect makeFRect(tagRECT rect){
		return null==rect
				?null
				:new FRect(
						rect.left
						,rect.top
						,rect.right-rect.left+1
						,rect.bottom-rect.top+1);		
	}
	/**
	 * 通用类型->底层类型
	 * @param rect
	 * @return FaceRect,rect为{@code null}时返回{@code null}
	 */
	private static final tagRECT toNative(FRect rect){
		return null==rect
				?null
				:new tagRECT(
						rect.getLeft()
						,rect.getTop()
						,rect.getLeft()+rect.getWidth()-1
						,rect.getTop()+rect.getHeight()-1);		
	}
	/**
	 * 底层类型->通用类型
	 * @param leftEye 左眼位置
	 * @param rightEye 右眼位置
	 * @return EyeInfo,leftEye或rightEye为{@code null}或所有的值为0时返回{@code null}
	 */
	private static final EyeInfo makeEyeInfo(tagPOINT	leftEye,tagPOINT	rightEye){		
		return null==leftEye||null==rightEye||(0==leftEye.x&&0==leftEye.y&&0==rightEye.x&&0==rightEye.y)
				?null
				:new EyeInfo(leftEye.x,leftEye.y,rightEye.x,rightEye.y);		
	}
	/**
	 * 通用类型->底层类型
	 * @param ei
	 * @return FacePoint,ei为{@code null}或所有的值为0时返回{@code null}
	 */
	private static final tagPOINT toNativeLeft(EyeInfo ei){
		return null==ei||(0==ei.getLeftx()&&0==ei.getLefty())
				?null:new tagPOINT(ei.getLeftx(),ei.getLefty());
	}
	/**
	 * 通用类型->底层类型
	 * @param ei
	 * @return FacePoint,ei为{@code null}或所有的值为0时返回{@code null}
	 */
	private static final tagPOINT toNativeRight(EyeInfo ei){
		return null==ei||(0==ei.getRightx()&&0==ei.getRighty())
				?null:new tagPOINT(ei.getRightx(),ei.getRighty());
	}
	/**
	 * 底层类型->通用类型
	 * @param point
	 * @return FInt2,point为{@code null}或所有的值为0时返回{@code null}
	 */
	private static final FInt2 makeFInt2(tagPOINT point){
		return null==point||(0==point.x&&0==point.y)
				?null:new FInt2(point.x,point.y);
	}
	/**
	 * 通用类型->底层类型
	 * @param point
	 * @return FacePoint,point为{@code null}或所有的值为0时返回{@code null}
	 */
	private static final tagPOINT toNative(FInt2 point){
		return null==point||(0==point.getX()&&0==point.getY())
				?null:new tagPOINT(point.getX(),point.getY());
	}
	/**
	 * 底层类型->通用类型
	 * @param angle
	 * @return FAngle,angle为{@code null}或所有的值为0时返回{@code null}
	 */
	private static final FAngle makeFAngle(FaceAngle angle){
		return null==angle||(0==angle.yaw&&0==angle.pitch&&0==angle.roll)
				?null:new FAngle(angle.yaw,angle.pitch,angle.roll,angle.confidence);
	}
	/**
	 * 通用类型->底层类型
	 * @param angle
	 * @return FAngle,angle为{@code null}或所有的值为0时返回{@code null}
	 */
	private static final FaceAngle toNative(FAngle angle){
		return null==angle||(0==angle.getYaw()&&0==angle.getPitch()&&0==angle.getRoll())
				?null:new FaceAngle(angle.getYaw(),angle.getPitch(),angle.getRoll(),angle.getConfidence());
	}
	/**
	 * 底层类型->通用类型
	 * @param ci
	 * @return CodeInfo,ci为{@code null}时返回{@code null}
	 */
	private static final CodeInfo makeCodeInfo(THFI_FacePos ci){
		return null==ci?null:
			new CodeInfo(null
					, makeFRect(ci.rcFace)
					, makeEyeInfo(ci.ptLeftEye,ci.ptRightEye)
					, makeFInt2(ci.ptMouth)
					, makeFInt2(ci.ptNose)
					, makeFAngle(ci.fAngle)
					, ci.pFacialData);
	}
	/**
	 * 通用类型->底层类型
	 * @param pos
	 * @return FacePos,pos为{@code null}时返回{@code null}
	 */
	private static final THFI_FacePos toNative(CodeInfo pos){
		return null==pos?null:
			new THFI_FacePos(
					  toNative(pos.getPos())
					, toNativeLeft(pos.getEi())
					, toNativeRight(pos.getEi())
					, toNative(pos.getMouth())
					, toNative(pos.getNose())
					, toNative(pos.getAngle())
					, 0
					, pos.getFacialData());
	}

	@Override
	public List detectFace(LazyImage lazyImg, final FRect detectRectangle)
			throws UnsupportedFormatException {
		concurrentLock.lock();
		try {
			Assert.notNull(lazyImg, "bufImg");
			// detectRectangle为空时,全图提取特征码
			Rectangle imgRect = lazyImg.getRectangle();
			Rectangle dr;
			if (null == detectRectangle){
				dr = imgRect;
			}else{
				// 如果指定的检测范围范围超出图像尺寸,则抛出异常
				RectUtils.assertContains(imgRect, "imgRect", dr = RectUtils.newRectangle(detectRectangle),
						"detectRectangle");
			}
			List faceInfo = new ArrayList();
			if (dr.width > 0 && dr.height > 0) {
				final byte[] imgRGB =getMatrixData(lazyImg, RectUtils.newFRect(dr));
				THFI_FacePos[] posArray = JniBridge.detectFace(imgRGB, 24, dr.width, dr.height);
				for (THFI_FacePos pos : posArray){
					faceInfo.add(makeCodeInfo(pos));
				}
				if (!RectUtils.isZeroPoint(dr)) {
					// 坐标系转换
					for (CodeInfo ci : faceInfo) {
						RectUtils.translate(ci, dr.x, dr.y);
					}
				}
			}
			return faceInfo;
		} finally {
			concurrentLock.unlock();
		}
	}
	@Override
	protected final CodeInfo getCodeFromImageMatrix(final byte[] imgMatrix, final int width, final int height,
			CodeInfo faceInfo, final AtomicBoolean hasFail) {
		Assert.notEmpty(imgMatrix, "imgMatrix");
		if (width <= 0 || height <= 0){
			throw new IllegalArgumentException(String.format("INVALID VALUE:the imgMatrix's size(%dW%dH) ", width,
					height));
		}
		Assert.notNull(faceInfo, "faceInfo");
		byte[] code = JniBridge.getFaceFeature(imgMatrix, width, height, toNative(faceInfo));
		if (null==code && null != hasFail){
			hasFail.set(true);
		}
		faceInfo.setCode(code);
		return faceInfo;
	}

	@Override
	protected byte[] getMatrixData(LazyImage lazyImg, FRect rect) throws UnsupportedFormatException {
		return lazyImg.getMatrixBGR(null==rect?null:RectUtils.newRectangle(rect));
	}

	@Override
	public List getCodeInfo(LazyImage lazyImg, int faceNum, List facePos) throws NotFaceDetectedException {
		concurrentLock.lock();
		// 检测到的人脸数目
		int faceCount = 0;
		// 提取到特征码的人脸数目
		int featureCount=0;
		final AtomicBoolean hasFail = new AtomicBoolean(false);
		try {
			Assert.notNull(lazyImg, "lazyImg");
			// facePos为null或空时抛出异常
			Assert.notEmpty(facePos, "facePos");
			// 人脸位置对象数目小于要求提取的特征码的数目,则抛出异常
			if (facePos.size() < faceNum){
				throw new NotFaceDetectedException(facePos.size(), 0);
			}
			byte[] imgData=getMatrixData(lazyImg,null);
			THFI_FacePos[] nativeArray = new THFI_FacePos[facePos.size()];
			for(int i=0;i 0)) {
				if (featureCount != faceNum){
					throw new NotFaceDetectedException(faceCount, featureCount);
				}
			} else if (0 == featureCount){
				throw new NotFaceDetectedException(faceCount, 0);
			}
			for(int i=0;i facePos = JniBridge.detectAndGetFeatures(imgData, lazyImg.getWidth(), lazyImg.getHeight());
			// 没有检测到要求的人脸则抛出异常
			if(0==facePos.size()){
				throw NOTFACEDETECTED_INSTANCE_DEFAULT;
			}
			if(faceNum>0&&faceNum!=facePos.size()){
				throw NOTFACEDETECTED_INSTANCE_DEFAULT;
			}
			CodeInfo[] ci = new CodeInfo[facePos.size()];
			int i = 0;
			CodeInfo element = null; 
			for(Entry entry:facePos.entrySet()){
				element = makeCodeInfo(entry.getKey());
				element.setCode(entry.getValue());
				ci[ i++ ] = element;
			}
			return ci;
		}finally{
			concurrentLock.unlock();
		}		
	}	
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy