科大訊飛開發者平臺上對外開放了語音和人臉識別的SDK。現在分享的人臉識別功能。
訊飛人臉識別的demo中有的在線人臉識別、離線人臉識別和視頻檢測三個功能。爲了更好的理解,我就簡單介紹這三個功能的作用。
人臉識別:主要的功能有人臉註冊、人臉檢測和人臉驗證。在線和離線只是實現的方式不一樣,其作用都一樣的。
視頻檢測:就是開啓攝像頭,檢測攝像頭的畫面是否是一個人臉。
對於這三個功能在它的demo中都很詳細,這裏就不多說。我現在分享的是先用視頻檢測功能獲取到攝像頭數據(某一幀的數據),然後用這張數據去進行人臉識別。
步驟1.集成SDK(見訊飛官方Doc)。
在看文檔時,我並沒有看到訊飛給開發者提供的返回的json格式。所以爲了偷懶,可以將FaceRect、FaceUtil和ParseResult類拷過來(可以自己打印後解析)。
步驟2.拷貝FaceRect、FaceUtil和ParseResult類到自己的工程裏。
步驟3.具體實現;假設已經成功完成了步驟1和步驟2。
新建一個PreviewActivity用來預覽和實現驗證功能。這個PreviewActivity的代碼大部分都是來自訊飛FaceDemo的com.iflytek.facedemo.VideoDemo類,因爲這個類實現了預覽和人臉檢測功能,這裏只需要加上驗證功能就可以了。驗證有在線和離線,這裏就說下在線驗證的了。在線驗證是要藉助com.iflytek.cloud.FaceRequest這個類。照着文檔建一個FaceRequest,mFaceRequest = new FaceRequest(this);設置參數之後調用mFaceRequest.sendRequest(mImageData, mRequestListener)就可以了。
那個這個參數要設置什麼參數呢?人臉註冊和其他功能需要的參數都不一樣(詳情見官方文檔),但是都需要一個保存了圖片數據的byte[]數組。這篇博客最主要的分享的也是怎
麼樣來獲取這個byte[]。
細心的人也許很容易發現我們在設置相機callback時(mCamera.setPreviewCallback()),可以在onPreviewFrame()回調中獲取到一個byte[],但是,這真的是我們需要的那個數
據嗎?沒錯,這個數據確實是相機一幀的數據。但是如果嘗試用這個數據來進行處理的話(人臉註冊或是驗證),你會發現並沒有成功,再嘗試用這個數據去轉成bitmap的話,返
回的null。問題又是在哪呢?
不要急,答案馬上揭曉。我們再留意一下相機的設置。
Parameters params=mCamera.getParameters();
params.setPreviewFormat(ImageFormat.NV21);
params.setPreviewSize(PREVIEW_WIDTH,PREVIEW_HEIGHT);
mCamera.setParameters(params);
發現什麼了嗎?是的,我們現在採集到的一幀的格式是NV21的,並不是RGB或者ARGB。
問題已經出來了,那麼只要將NV21的數據轉RGB就行了。這裏有個網上找的方法。
public static int[] convertYUV420_NV21toRGB8888(byte[] data, int width, int height) { int size = width * height; int offset = size; int[] pixels = new int[size]; int u, v, y1, y2, y3, y4; // i percorre os Y and the final pixels // k percorre os pixles U e V for (int i = 0, k = 0; i < size; i += 2, k += 2) { y1 = data[i] & 0xff; y2 = data[i + 1] & 0xff; y3 = data[width + i] & 0xff; y4 = data[width + i + 1] & 0xff; u = data[offset + k] & 0xff; v = data[offset + k + 1] & 0xff; u = u - 128; v = v - 128; pixels[i] = convertYUVtoRGB(y1, u, v); pixels[i + 1] = convertYUVtoRGB(y2, u, v); pixels[width + i] = convertYUVtoRGB(y3, u, v); pixels[width + i + 1] = convertYUVtoRGB(y4, u, v); if (i != 0 && (i + 2) % width == 0) i += width; } return pixels; } private static int convertYUVtoRGB(int y, int u, int v) { int r, g, b; r = y + (int) 1.402f * v; g = y - (int) (0.344f * u + 0.714f * v); b = y + (int) 1.772f * u; r = r > 255 ? 255 : r < 0 ? 0 : r; g = g > 255 ? 255 : g < 0 ? 0 : g; b = b > 255 ? 255 : b < 0 ? 0 : b; return 0xff000000 | (b << 16) | (g << 8) | r; }
轉出之後再轉圖片(bitmap)就行了,有部分相機方向不對需要相應的設置圖片的方向,圖片方向對驗證或者註冊很重要。旋轉圖片的方法有很多很多人也知道,這裏就不再贅述了。
在線視頻的主要技術是不是就是數據格式呢?哈哈!
demo傳不上,不知道爲什麼會傳不上。