科大訊飛視頻檢測並驗證

  科大訊飛開發者平臺上對外開放了語音和人臉識別的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傳不上,不知道爲什麼會傳不上。

  

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