2016年11月16日 星期三

JavaScript 之 Array 詳解

Array.prototype.concat()

Syntax

var new_array = old_array.concat(value1[, value2[, …[, valueN]]])

可以連接多個Array,不會改變原本的Array,但會回傳一個連接後的Array

let arr = [1,2,3];
let concat_arr = arr.concat(['a','b','c']);

console.log(concat_arr);
// [1, 2, 3, 'a', 'b', 'c']

加入連接的值可以是 String、Number 或 Boolean

let arr = [1,2,3]
let str = String('STR');
let num = Number(5);
let boolean = Boolean(true);
let concat_arr = arr.concat(str, num, boolean);

console.log(concat_arr);
// [1, 2, 3,'STR', 5, true]

如果是 new String、 new Number、 new Boolean 會是以物件型態加入

let arr = [1,2,3]
let str = new String('STR');
let num = new Number(5);
let boolean = new Boolean(true);
let concat_arr = arr.concat(str, num, boolean);

console.log(concat_arr);
// [ 1, 2, 3, [String: 'STR'], [Number: 5], [Boolean: true] ]

Array.prototype.every()

Syntax

arr.every(callback[, thisArg])

針對 Array 裡每個值做處理,所有都滿足條件回傳 true,否則回傳 false

function isBigEnough(element, index, array) {
    return element >= 10;
}

let res = [12, 5, 8, 130, 44].every(isBigEnough);
console.log(res);
// false

也可以寫成箭頭函式

let res = [12, 5, 8, 130, 44].every(elem => elem >= 10);
console.log(res);
// false

Array.prototype.fill()

Syntax

arr.fill(value)
arr.fill(value, start)
arr.fill(value, start, end)

這裡會使用到三個變數,value 是指填充在Array的值,start 指的是起始位置,初始值是 0 ,end 指的是結束位置,初始值是 Array.length。

let arr = [1, 2, 3, 4, 5];
arr.fill(5); // [ 5, 5, 5, 5, 5 ]
arr.fill(value = 5, start = 0, end = arr.length); // [ 5, 5, 5, 5, 5 ]
arr.fill(5, 1); // [ 1, 5, 5, 5, 5 ]
arr.fill(5, 1, 3); // [ 1, 5, 5, 4, 5 ]
arr.fill(5, -2); // [ 1, 2, 3, 5, 5 ]
arr.fill(5, -6); // [ 5, 5, 5, 5, 5 ]

Array.prototype.filter()

Syntax

var new_array = arr.filter(callback[, thisArg])

列出Array內的值大於10

function isBigEnough(element, index, array) {
    return element >= 10;
}

let res = [12, 5, 8, 130, 44].filter(isBigEnough);
console.log(res);
// [12, 130, 44]

舉一個例子,過濾帳號資料含 usernamepassword的列表。

let obj_arr = [{
    username: 'marc',
    password: 'A123456'
}, {
    username: 'marc_1',
    password: 'B123456'
}, {
    username: 'marc_2'
}, {
    email: 'marc@gmail.com'
}]

function accountFilter(acc) {
    return (acc.username !== undefined && acc.password !== undefined) ? true : false;
}

let res = obj_arr.filter(accountFilter);
console.log(res);
// [ { username: 'marc', password: 'A123456' },{ username: 'marc_1', password: 'B123456' } ]
continue reading JavaScript 之 Array 詳解

2016年11月13日 星期日

Javascript 之排序演算法 ( Sort Algorithm )

氣泡排序法 ( Bubble Sort )

從第一筆開始,每相鄰兩筆比較,大小交換位置,大的在右,小的在左,以此類退,直到最後一筆。 不斷的循環直到都沒有交換為止。

時間複雜度 ( Time Complexity )

  • Best Case:Ο(n)
  • Worst Case:Ο(n2)
  • Average Case:Ο(n2)
(8)~(5)~(7)~(2)~(3)~(9)~(4)~(6) - 8、5(處理值)
(5)~(8)~(7)~(2)~(3)~(9)~(4)~(6) - 8、7(處理值)
(5)~(7)~(8)~(2)~(3)~(9)~(4)~(6) - 8、2(處理值)
(5)~(7)~(2)~(8)~(3)~(9)~(4)~(6) - 8、3(處理值)
(5)~(7)~(2)~(3)~(8)~(9)~(4)~(6) - 8、9(處理值)
(5)~(7)~(2)~(3)~(8)~(9)~(4)~(6) - 9、4(處理值)
(5)~(7)~(2)~(3)~(8)~(4)~(9)~(6) - 9、6(處理值)
(5)~(7)~(2)~(3)~(8)~(4)~(6)~(9)
(5)~(7)~(2)~(3)~(8)~(4)~(6)~(9) - 5、7(處理值)
(5)~(7)~(2)~(3)~(8)~(4)~(6)~(9) - 7、2(處理值)
(5)~(2)~(7)~(3)~(8)~(4)~(6)~(9) - 7、3(處理值)
(5)~(2)~(3)~(7)~(8)~(4)~(6)~(9) - 7、8(處理值)
(5)~(2)~(3)~(7)~(8)~(4)~(6)~(9) - 8、4(處理值)
(5)~(2)~(3)~(7)~(4)~(8)~(6)~(9) - 8、6(處理值)
(5)~(2)~(3)~(7)~(4)~(6)~(8)~(9)
(5)~(2)~(3)~(7)~(4)~(6)~(8)~(9) - 5、2(處理值)
(2)~(5)~(3)~(7)~(4)~(6)~(8)~(9) - 5、3(處理值)
(2)~(3)~(5)~(7)~(4)~(6)~(8)~(9) - 5、7(處理值)
(2)~(3)~(5)~(7)~(4)~(6)~(8)~(9) - 7、4(處理值)
(2)~(3)~(5)~(4)~(7)~(6)~(8)~(9) - 7、6(處理值)
(2)~(3)~(5)~(4)~(6)~(7)~(8)~(9)
(2)~(3)~(5)~(4)~(6)~(7)~(8)~(9) - 2、3(處理值)
(2)~(3)~(5)~(4)~(6)~(7)~(8)~(9) - 3、5(處理值)
(2)~(3)~(5)~(4)~(6)~(7)~(8)~(9) - 5、4(處理值)
(2)~(3)~(4)~(5)~(6)~(7)~(8)~(9) - 5、6(處理值)
(2)~(3)~(4)~(5)~(6)~(7)~(8)~(9)
function swap(arr, i, j) {
    let tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

function bubbleSort(arr) {
    for (let i = 0; i < arr.length; i++) {
        let swap = false;
        for (let j = 0; j < arr.length - i; j++) {
            if (arr[j] > arr[j + 1]) {
                let tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
                swap = true;
            }
        }
        if (!swap) {
            break;
        }
    }
}

swap:檢查是否已經完成排序,如果都沒有執行交換,代表已完成可以提前結束排序。

插入排序法 ( Insertion Sort )

時間複雜度 ( Time Complexity )

  • Best Case:Ο(1)
  • Worst Case:Ο(n2)
  • Average Case:Ο(n2)
(8)~(5)~(7)~(2)~(3)~(9)~(4)~(6) - 8(處理值)
(8)~(5)~(7)~(2)~(3)~(9)~(4)~(6) - 5(處理值)
(5)~(8)~(7)~(2)~(3)~(9)~(4)~(6)
(5)~(8)~(7)~(2)~(3)~(9)~(4)~(6) - 7(處理值)
(5)~(7)~(8)~(2)~(3)~(9)~(4)~(6)
(5)~(7)~(8)~(2)~(3)~(9)~(4)~(6) - 2(處理值)
(5)~(7)~(2)~(8)~(3)~(9)~(4)~(6)
(5)~(2)~(7)~(8)~(3)~(9)~(4)~(6)
(2)~(5)~(7)~(8)~(3)~(9)~(4)~(6)
(2)~(5)~(7)~(8)~(3)~(9)~(4)~(6) - 3(處理值)
(2)~(5)~(7)~(3)~(8)~(9)~(4)~(6)
(2)~(5)~(3)~(7)~(8)~(9)~(4)~(6)
(2)~(3)~(5)~(7)~(8)~(9)~(4)~(6)
(2)~(3)~(5)~(7)~(8)~(9)~(4)~(6) - 4(處理值)
(2)~(3)~(5)~(7)~(8)~(4)~(9)~(6)
(2)~(3)~(5)~(7)~(4)~(8)~(9)~(6)
(2)~(3)~(5)~(4)~(7)~(8)~(9)~(6)
(2)~(3)~(4)~(5)~(7)~(8)~(9)~(6)
(2)~(3)~(4)~(5)~(7)~(8)~(9)~(6) - 6(處理值)
(2)~(3)~(4)~(5)~(7)~(8)~(6)~(9)
(2)~(3)~(4)~(5)~(7)~(6)~(8)~(9)
(2)~(3)~(4)~(5)~(6)~(7)~(8)~(9)
function swap(arr, i, j) {
    let tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

function insertion(arr) {
    for (let i = 0; i < arr.length; i++) {
        for (let j = i; j >= 0; j--) {
            if (arr[j + 1] < arr[j]) {
                swap(arr, j, j + 1)
            } else {
                continue;
            }
        }
    }
}

選擇排序法 ( Selection Sort )

搜尋最小值,與第一值交換位置,再找第二個最小值,與第二個值交換位置,以此類推,直到排序完成。

時間複雜度 ( Time Complexity )

  • Best Case:Ο(n2)
  • Worst Case:Ο(n2)
  • Average Case:Ο(n2)

空間複雜度 ( Space Complexity )

  • θ(1)
(8)~(5)~(7)~(2)~(3)~(9)~(4)~(6) - 2(處理值)
(2)~(5)~(7)~(8)~(3)~(9)~(4)~(6)
(2)~(5)~(7)~(8)~(3)~(9)~(4)~(6) - 3(處理值)
(2)~(3)~(7)~(8)~(5)~(9)~(4)~(6)
(2)~(3)~(7)~(8)~(5)~(9)~(4)~(6) - 4(處理值)
(2)~(3)~(4)~(8)~(5)~(9)~(7)~(6)
(2)~(3)~(4)~(8)~(5)~(9)~(7)~(6) - 5(處理值)
(2)~(3)~(4)~(5)~(8)~(9)~(7)~(6)
(2)~(3)~(4)~(5)~(8)~(9)~(7)~(6) - 6(處理值)
(2)~(3)~(4)~(5)~(6)~(9)~(7)~(8)
(2)~(3)~(4)~(5)~(6)~(9)~(7)~(8) - 7(處理值)
(2)~(3)~(4)~(5)~(6)~(7)~(9)~(8)
(2)~(3)~(4)~(5)~(6)~(7)~(9)~(8) - 8(處理值)
(2)~(3)~(4)~(5)~(6)~(7)~(8)~(9)
function swap(arr, i, j) {
    let tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

function selection(arr) {
    let tmp = [];
    for (let i = 0; i < arr.length; i++) {
        let min = i;
        for (let j = i + 1; j < arr.length; j++) {
            if (arr[min] > arr[j]) {
                min = j;
            }
        }
        if (i != min) {
            swap(arr, min, i);
        }
    }
}
continue reading Javascript 之排序演算法 ( Sort Algorithm )

2016年11月10日 星期四

Python 學習之路 - Built-in Functions

abs(x)

描述:

返回絕對值,可接受的輸入值型態為整數、浮點數、長整數

( 2.5版以後支援 )

範例:

>>> abs(0.55)
# 0.55

>>> abs(-0.55)
# 0.55

>>> abs(-5)
# 5

>>> abs(5)
# 5

>>> abs(123.456)
# 123.456

>>> abs(-123.456)
# 123.456

all(iterable)

描述:

判斷 iterable 內的所有元素不包含 0''False或者None,滿足條件則返回 True,否則為 False

( 2.5版以後支援 )

同下列函式

def all(iterable):
    for element in iterable:
        if not element:
            return False
    return True

範例:

>>> all([False, True, True])
# False ,其中有一個值為 False

>>> all([True, True, True])
# True ,全部都滿足條件

>>> all(['123', '456', '789'])
# True ,全部都滿足條件

>>> all(['123', '', '789'])
# False ,其中有一個值為 ''

>>> all((0, 1, 2, 3))
# False ,其中有一個值為 0

>>> all((7, 8, 9, 10))
# True ,全部都滿足條件

>>> all((1, None, 2))
# False ,其中有一個值為 None

>>> all(({'a': 0}, {'b': 1}))
# True ,全部都滿足條件

>>> all([])
# True ,空列表(List)為真

>>> all(())
# True ,空元组(Tuple)為真

any(iterable)

描述:

判斷 iterable 內的所有元素都為 0''False或者None,滿足條件則返回 False,否則為 True,只要其中一個不滿足就返回 True

( 2.5版以後支援 )

同下列函式

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

範例:

>>> any([False, '', None])
# False ,三個值皆滿足條件

>>> any([False, True, True])
# True ,其中兩個值為 True 

>>> any([False, False, False])
# False ,三個值皆為 False

>>> any(['', '', ''])
# False ,三個值皆為 ''

>>> any(['123', '', '789'])
# True ,其中兩個值為字串

>>> any((0, 1, 2, 3))
# True ,其中三個值不為0的整數

>>> any((0, 0, 0, 0))
# False ,四個值皆為 0

>>> any((1, None, 2))
# True 

>>> any(({'a': 0}, {'b': 1}))
# True

>>> any([])
# False

>>> any(())
# False

range([start], stop[, step])

描述:

產生整數序列,參數 start 為起始值,stop 為結束值, step 為間隔值,如果可以建議使用 xrange 取代 range,因為 range 每次都要先建立序列,如果數量大的話容易導致記憶體耗損及計算速度

範例:

>>> range(1, 5, 1)
# [1,2,3,4] ,1到5(不包含5)

>>> range(1, 5, 2)
# [1,3] ,1到5,每間隔2(不包含5)

>>> range(5)
# [0,1,2,3,4] ,0到5(不包含5)

>>> range(0, -5, -1)
# [0,-1,-2,-3,-4]

for i in range(1, 5, 1):
    print i
# 1,2,3,4

for i in xrange(1, 5, 1):
    print i
# 1,2,3,4

array = [1, 2, 3, 4, 5, 6, 7]
for i in range(len(array)):
    print array[i]
# 1,2,3,4,5,6,7

array = [1, 2, 3, 4, 5, 6, 7]
for i in range(len(array) - 1, -1, -1):
    print array[i]
# 7,6,5,4,3,2,1

參考 Python Doc

continue reading Python 學習之路 - Built-in Functions

2016年8月29日 星期一

NodeJS Async Methods (Callback, Promise, Generator)

Callback

一般遇到需要非同步的函數都會使用 Callback,這裡使用 setTimeout 模擬調用一個非同步的API,執行完調用 callback 函數傳送結果回去,如果單純只有ㄧ個簡單的非同步運算,當然可以這樣寫簡單又明瞭。
function callbackFunc(delayTime, cb) {
    setTimeout(() => {
        cb(null, delayTime);
        return;
    }, delayTime);
}
假設今天有一個邏輯需要調用多個非同步函數才可完成的流程,以下例子是執行3個非同步函數時撰寫的方式,會造成程式碼過多的階層,長得很醜也很難除錯。
callbackFunc(1000, (err, value) => {
    if (err) {
        console.log(err)
    } else {
        console.log(`call first function was done in ${value}ms using callback`);
        callbackFunc(value * 2, (err, value) => {
            if (err) {
                console.log(err)
            } else {
                console.log(`call second function was done in ${value}ms using callback`);
                callbackFunc(value * 2, (err, value) => {
                    if (err) {
                        console.log(err)
                    } else {
                        console.log(`call final function was done in ${value}ms using callback`);
                    }
                })
            }
        })
    }
})

Promise

有了 Promise 的出現後,撰寫非同步的函數又多了一個選擇。
function promiseFunc(delayTime) {
    return new Promise((resolve, reject) => {
        setTimeout((value) => {
            if (delayTime < 2000) resolve(delayTime);
            else reject(delayTime);
            return;
        }, delayTime);
    })
}
但如果一樣遇到需要使用多個非同步時,千萬 不要 像以下這樣直接多個階層式寫下去。
promiseFunc(1000)
    .then((value) => {
        console.log(`call first function was done in ${value}ms using promise`);
        promiseFunc(value * 2)
            .then((value) => {
                console.log(`call second function was done in ${value}ms using promise`);
                promiseFunc(value * 2)
                    .then((value) => {
                        console.log(`call final function was done in ${value}ms using promise`);
                    })
                    .catch((error) => {
                        console.log(`Promise Error: ${error}`);
                    })
            })
            .catch((error) => {
                console.log(`Promise Error: ${error}`);
            })
    })
    .catch((error) => {
        console.log(`Promise Error: ${error}`);
    })
其實可以收斂成以下這樣的寫法:
promiseFunc(1000)
    .then((value) => {
        console.log(`call first function was done in ${value}ms using promise`);
        return promiseFunc(value * 2);
    })
    .then((value) => {
        console.log(`call second function was done in ${value}ms using promise`);
        return promiseFunc(value * 2);
    })
    .then((value) => {
        console.log(`call final function was done in ${value}ms using promise`);
    })
    .catch((error) => {
        console.log(`Promise Error: ${error}`);
    })
或者在更精簡使用 箭頭 函數的方式
promiseFunc(1000)
    .then(value => promiseFunc(value * 2))
    .then(value => promiseFunc(value * 2))
    .then(value => {
        console.log(`call final function was done in ${value}ms using promise`);
    })
    .catch(error => console.log(`Promise Error: ${error}`));

Generator

Case 1

將計算較久的函數改成 Generator 非同步 。
function asyncFunc(delayTime) {
    if (delayTime === 0) {
        setTimeout(() => { workProc.next({ result: true, value: delayTime }) }, 0);
    } else {
        setTimeout((value) => {
            if (delayTime < 2000) workProc.next({ result: true, value: delayTime });
            else workProc.next({ result: false, value: delayTime });
            return;
        }, delayTime);
    }
}


function* generatorWorker() {
    let readyWorker1 = yield asyncFunc(0);
    console.log(`call first function was done in ${readyWorker1.value}ms using promise`);
    let readyWorker2 = yield asyncFunc(1000);
    console.log(`call second function was done in ${readyWorker2.value}ms using promise`);
    let readyWorker3 = yield asyncFunc(2000);
    console.log(`call final function was done in ${readyWorker3.value}ms using promise`);
}
let workProc = generatorWorker();
workProc.next(); //進入generatorWorker直到第一個yield停止

Case 2

將原本使用 Callback 的函數改成 Generator 。
function callbackFunc(delayTime, cb) {
    setTimeout(() => {
        cb(null, delayTime);
        return;
    }, delayTime);
}

function callbackFuncPackage(delayTime) {
    callbackFunc(delayTime, (err, value) => {
        if (err) {
            workProc.next({ result: false, value: value });
        } else {
            workProc.next({ result: true, value: value });
        }
    })
}

function* generatorWorker() {
    let readyWorker1 = yield callbackFuncPackage(1000);
    if (readyWorker1.result) console.log(`call first function was done in ${readyWorker1.value}ms using generator`);
    let readyWorker2 = yield callbackFuncPackage(readyWorker1.value * 2);
    if (readyWorker2.result) console.log(`call second function was done in ${readyWorker2.value}ms using generator`);
    let readyWorker3 = yield callbackFuncPackage(readyWorker2.value * 2);
    if (readyWorker3.result) console.log(`call final function was done in ${readyWorker3.value}ms using generator`);

}

let workProc = generatorWorker();
workProc.next();

Case 3

將原本使用 Promise 的函數改成 Generator 。
function promiseFunc(delayTime) {
    return new Promise((resolve, reject) => {
        setTimeout((value) => {
            resolve(delayTime);
            return;
        }, delayTime);
    })
}

function promiseFuncPackage(delayTime) {
    promiseFunc(delayTime)
        .then((value) => {
            workProc.next({ result: true, value: value });
            return;
        })
        .catch((error) => {
            workProc.next({ result: false, value: error });
        })
}

function* generatorWorker() {
    let readyWorker1 = yield promiseFuncPackage(1000);
    if (readyWorker1.result) console.log(`call first function was done in ${readyWorker1.value}ms using generator`);
    let readyWorker2 = yield promiseFuncPackage(readyWorker1.value * 2);
    if (readyWorker2.result) console.log(`call second function was done in ${readyWorker2.value}ms using generator`);
    let readyWorker3 = yield promiseFuncPackage(readyWorker2.value * 2);
    if (readyWorker3.result) console.log(`call final function was done in ${readyWorker3.value}ms using generator`);

}

let workProc = generatorWorker();
workProc.next();

Case 4

當原本有多個 Promise 函數,且有前後順序邏輯關係時,可以寫一個遞迴函數專門處理。
function promiseFunc(delayTime) {
    return new Promise((resolve, reject) => {
        setTimeout((value) => {
            resolve(delayTime);
            return;
        }, delayTime);
    })
}

function* generatorWorker(value) {
    console.log(`value : ${value}`);
    let value1 = yield promiseFunc(value);
    console.log(`call first function was done in ${value1}ms using generator`);
    let value2 = yield promiseFunc(value1 * 2);
    console.log(`call first function was done in ${value2}ms using generator`);
    let value3 = yield promiseFunc(value2 * 2);
    console.log(`call first function was done in ${value3}ms using generator`);
}

let workProc = generatorWorker(1000);

function processGenerator(workProc, value) {
    let readyWork = workProc.next(value);
    if (readyWork.done) {
        return;
    } else {
        readyWork.value
            .then((value) => {
                processGenerator(workProc, value);
                return;
            })
            .catch((error) => {
                return; 
            })
    }
}

processGenerator(workProc);
詳細程式碼請參考example-async
continue reading NodeJS Async Methods (Callback, Promise, Generator)

2016年6月19日 星期日

Facial Recognition(人臉辨識、人脸识别、顔認識システム、얼굴 인식)

Facial Recognition(人臉辨識、人脸识别、顔認識システム、얼굴 인식)

人臉辨識技術的研究始於1960年代末期,但一直到1990年代後期,一些商業性的人臉辨識系統,才開始進入市場,所以Face Recognition人臉辨識屬於新的技術,也是未來生物辨識中相當重要的一環,以下是我目前所注意的一些人臉辨識公司以及目前的技術和產品。Human-Computer Interaction (HCI)雖然現在人臉辨識率已經達到90%以上,但環境的變化依然是最大的問題。
2D人臉辨識技術已經走到技術的瓶頸,不管是傳統的電腦視覺演算法還是近來火紅的深度學習都各有優缺點,但實際應用的情境中,時常遇到的利用照片或影片欺騙攝影機已達到通過辨識。後來有人使用3D人臉辨識技術加以防範,因為多一層深度特徵可以計算是否為活體。近年許多公司提出使用人臉辨識結合RFID或BEACON、指紋等相關技術,利用雙重關卡以確保防止誤判,或者提升辨識速度。但一開始使用人臉辨識最主要的初衷就是不需要再攜帶其他可身分驗證的裝置。都各有利弊。
目前手機App廣泛使用Face Detection 及 Feature Extraction這兩類的服務,最常見的就是修圖軟體或者是影片遮罩的應用。目前有很多公司都有提供線上的WebAPI供大家開發,在移動裝置更提供ios及android的SDK。算是非常普遍的技術支援。以下文章也有提供幾家公司可參考。
目前使用人臉辨識常遇到的瓶頸,當需比對的人臉資料庫太大時辨識率會下降及辨識速度的問題。無法在同場域幫該使用者建檔,必須透過其他途徑建檔,如證件或照片等來源當作建檔,這都會大大影響辨識率的效果。環境光線隨著時間變化改變大也會大大影響辨識結果。
大部分的人分不清楚人臉偵測與人臉辨識,經常可以看到一些文章或者新聞標題寫著人臉辨識技術,但實際點進去才發現只是人臉偵測,到底差別在哪裡?請看下列一個簡易流程圖。

整個流程可以再細分為:

其實,從人臉可得到的資訊並不只有身分辨識,比如說可以得知表情、性別、年齡、眼鏡及眼睛視角等應用。
美國聯邦公平交易委員(Federal Trade Commission)對人臉辨識科技提出幾項建議:
- 研發及利用臉部辨識科技的公司,要保持客戶臉型數據的安全及隱密。
- 不能永久保持客戶的臉部數位資訊。
- 不能在有個人隱私顧慮的地方架設辨識系統,如洗手間,更衣室,醫療中心,並應避免拍攝兒童。
- 需要有招牌註明辨識系統在運作。
- 社群網路如臉書應該要有開關辨識系統的功能。
- 如要收集臉部資訊,需要先告知。
- 不使用「辨識陌生人」功能,除非被辨識者巳經同意被別人辨識。產業分析界指出,臉部辨識科技有如一把雙面利劍;一方面可以有效的保護個人隱私;另一方面有可能失去個人隱私。

商業應用

零售業
- 利用人臉偵測判斷消費者是否觀看廣告或商品。
- 預估消費者年齡及性別判斷廣告吸引主要目標,以利量測廣告效益。
- 整合POS機加入消費者年齡及性別資訊,事後統計商品消費資訊使用。
- 使用人臉追蹤技術計算消費者觀看商品或廣告時間。
- 透過人臉辨識VIP客戶名單,快速且到位服務重要賓客。
- 使用微笑預估提升店員服務態度及消費者滿意度。
監控業
- 辨識所有進入家中的人員,防止小偷。
- 身分驗證
- 可疑人士提醒

各國人臉偵測用語

  • 台灣 - 人臉偵測
  • 中國 - 人脸檢測
  • 日本 -
  • 美國 - Face Detection
  • 韓國 - 얼굴 인식

各國人臉辨識用語

  • 台灣 - 人臉辨識
  • 中國 - 人脸识别、人像识别、面部识别
  • 日本 - 顔認識、システム
  • 美國 - Facial Recognition
  • 韓國 - 얼굴 인식

人臉辨識的障礙

  • 光線變化(illumination )
    • 單方向性強光
    • 陰影
  • 姿勢變化(pose changes)
    • 俯仰角過大、側臉
  • 表情變化(facial expression)
    • 大笑
  • 年齡改變(age variation)
    • 皺紋
    • 五官深度
  • 臉部遮蔽(occlusions)
    • 墨鏡
    • 帽子
    • 口罩

研究方法 Research Methods

  • knowledge-based method(自己何謂定義人臉)
  • feature invariant approaches(人臉結構特徵)
  • template matching methods(建立人臉雛形比對)
  • appearance-based methods(臉的外型邊緣)
  • Algorithm
    • Active Shape Model(ASM)
    • Active Appearance Model(AAM)
    • AdaBoost
    • Covolutional Neuron Networks(CNN)
    • Deep neural networks(DNNs)
    • EigenFace
    • FisherFace
    • Gray Scale
    • Gabor Filter
    • Hidden Markov Models (HMM)
    • Histogram of Oriented Gradients(HOG)
    • Histogram of Shearlet Coefficients(HSC)
    • Linear Discriminant Analysis(LDA)
    • Local Binary Pattern(LBP)
    • Local Directional Pattern(LDP)
    • Local Ternary Pattern(LTP)
    • Local Tetra Pattern(LTrP)
    • Local Adaptive Teranry Pattern(LATP)
    • Local Gabor Binary Pattern(LGBP)
    • Local Vector Pattern(LVP)
    • Nearest Neighbor(NN)
    • Sobel Filter
    • Support Vector Machine(SVM)
    • Sparse Representation Classification(SRC)
    • Scale-Invariant Feature Transform(SIFT)
    • Speed-Up Robust Feature(SURF)
    • Tracking-Learning-Detection(TLD)
    • Part-Gabor Filter
    • Principal Component Analysis(PCA)
    • Patterns of Oriented Edge Magnitudes(POEM)
  • Image Processing
    • Histogram Specification
    • Histogram Equalization
    • Gamma Correction
    • Difference of Gaussion Filter
    • Contrast Equalization

資源 Open Source

學習平台

研究單位

應用 Application

相關公司 Related Company

倚辰 【台灣】【產品】
笛林傑 【台灣】【產品】
天誠盛業 【中國】【產品】
中自維森 【中國】【產品】
汉王 【中國】【產品】
基嘉科技 【台灣】【產品】
石安 【中國】【產品】【解決方案】
眾智益華 【中國】【產品】【解決方案】
飛瑞斯 【中國】【產品】【解決方案】
途拓 【中國】【產品】
智慧眼 【中國】【產品】【解決方案】
瑞為 【中國】【產品】【SDK】
寶島極光 【台灣】【產品】【解決方案】
遠漢 【台灣】【產品】
怡群 【台灣】【產品】
怡鑫 【台灣】【產品】
銀瀑【中國】【產品】
螢石【中國】【家庭監控】【產品】
銳控【中國】【產品】
騰訊 【中國】【WebAPI】
Acsys 【產品】【SDK】【加拿大】
ApiCloud.Me 【WebAPI】
Alchemy【WebAPI】
Avalon Biometrics【西班牙】【產品】【解決方案】【SDK】
Animetrics 【美國】【產品】【解決方案】【SDK】【WebAPI】
Ayonix【產品】【SDK】【日本】
Betaface 【德國】【SDK】【WebAPI】
BioID 【德國】【產品】【解決方案】【WebAPI】
Biometrypass 【智利】【產品】
Crossmatch 【美國】【產品】
CeeQ 【WebAPI】
Cybula 【英國】【產品】
CityLive【英國】【產品】
EyeDea 【捷克】【產品】【WebAPI】
FaceCash 【WebAPI】
Face++ 【中國】【WebAPI】
FaceR 【WebAPI】
Face-six
Google 【WebAPI】
Hyperlayer【美國】【SDK】
iOmnsicient’s【產品】
Kairos【美國】【WebAPI】
KeyLemon 【WebAPI】【SDK】
LinkFace【中國】【WebAPI】
LYKAON 【日本】【產品】
Lambda Labs 【美國】【WebAPI】
Luxand 【SDK】【產品】【WebAPI】
Moodru【美國】【產品】
Neurotechnology 【歐洲】【SDK】
NEC 【日本】【產品】【解決方案】【SDK】
OpenFace 【WebAPI】
Pixuate 【WebAPI】【Service】
PUX 【產品】
ReKognition 【美國】【WebAPI】
Recon【中國】【產品】【SDK】
Seeing Machines【美國】【產品】【解決方案】【SDK】
SimpliCam【家庭監控】【產品】
Sightcorp【荷蘭】【產品】【SDK】
SkyBiometry 【美國】【WebAPI】
Tastenkunst【德國】【SDK】
Viulib【產品】【SDK】
TCIT 【台灣】【產品】【解決方案】【SDK】【WebAPI】

常用的人臉資料庫 Face Database

The AR Face Database
4,000 color images corresponding to 126 people’s faces
BioID Face Database
1521 gray level images
The CMU Multi-PIE Face Database
750,000 images of 337 people
The Japanese Female Facial Expression (JAFFE) Database
213 images of 7 facial expressions
Labeled Faces in the Wild
13,000 images of faces
Labeled Wikipedia Faces (LWF)
8,500 faces for about 1,500 identities, taken from Wikipedia
Yale Face Database
165 grayscale images in GIF format of 15 individuals
更多的人臉資料庫請參考:人臉資料庫
【相關新聞 Related News】
2016.03.25-NEC表示辨識速度達到1秒300萬筆
2016.01.02-台灣銀行結合人臉辨識技術迎賓
2015.12.10-豪宅電梯結合人臉辨識
2015.11.01-Google 相簿人臉辨識搜尋支援台灣
2015.08.26-智慧監控與辨識、智慧製造展出人臉辨識大數據分析
2015.07.30-Win10支援人臉辨識開機
2015.06.16-Facebook發表相片分享App 具人臉辨識功能
2015.05.30-中國發表第一台人臉辨識ATM
2015.05.22-思科發表智慧視訊會議系統,透過聲音、人臉偵測自動追踨發言者
2015.05.01-微軟 How-old.net 魅力引起大家關注人臉辨識熱門的WebAPI平台
2015.03.29-ATM可望使用人臉辨識領錢
2015.03.24-美國機場導入人臉辨識測試
2015.03.03-AVG提出對抗人臉辨識的眼鏡
2015.02.20-入歐旅客將實施指紋加人臉辨識
2015.02.09-日本飯店使用機器人取代人力,並以人臉辨識取代鑰匙
2014.12.18-販賣機靠著人臉辨識推薦購買者
2014.11.06-前線媒體結合人臉辨識吸引Intel投資
2014.11.05-中國人臉辨識公司Face++完成B輪美金2200萬融資
2014.09.24-零售業導入人臉辨識啟動全新商業模式
2014.09.07-中科院開發人臉辨識線上支付系統
2014.09.03-保全業者導入人臉辨識門禁系統
2014.08.13-台灣之星101旗艦店結合人臉辨識分析客群精準行銷
2014.07.30-比利時首都布魯塞爾市札文騰機場於2015年啟用人臉辨識通關
2014.07.18-實體零售業結合人臉辨識提升銷售目標
2014.06.12-人臉辨識驗證考生真實身分
2014.06.05-Amazon推出人臉辨識功能的手機
2014.06.03-BesEye推出人臉辨識雲端監控系統
2014.05.25-中國成都醫院導入人臉辨識系統防鬧事人士
2014.05.22-Panasonic電視支援人臉辨識開機
2014.05.21-漢王人臉辨識產品疑似有漏洞
2014.04.20-日本機場重新啟動人臉辨識結合晶片過關
2014.03.21-女警利用手機人臉辨識系統抓小偷
2014.02.27-日本NTT DoCoMo展出人臉辨識智慧型眼鏡
2014.02.26-警方利用人臉辨識系統幫老婦找回家的路
2014.01.15-Intel與前線媒體合作導入人臉辨識系統精準廣告行銷
2014.01.05-失智人口走失,依靠人臉辨識系統找回家的路
2013.11.20-軍人結夥搶劫,警方靠人臉辨識系統抓人
2013.10.30-販賣機依人臉資訊推薦商品
2013.09.25-西安城東客運站設置人臉辨識的電子置物櫃
2013.09.05-人臉及聲音辨識公司KeyLemon獲得150萬美元投資
2013.08.21-前線媒體利用人臉關注廣告程度營造年收上百億
2013.07.30-收銀機利用人臉辨識提升服務品質
2013.07.20-利用人臉辨識技術取代麻煩的付費機制
2013.06.18-台北101推出智慧化購物環境,鼎泰豐門口架設人臉性別分析
2013.06.15-大陸女子整形加假指紋還是騙不了人臉辨識系統
2013.05.30-利用人臉辨識防止司機瞌睡

反人臉辨識(Anti-Facial Recognition)
CV Dazzle Anon Salon

人臉辨識相關職缺

所有資訊持續更新,如有錯誤或觸犯貴公司資訊請告知
continue reading Facial Recognition(人臉辨識、人脸识别、顔認識システム、얼굴 인식)

OpenCV Tutorial (學習筆記)

Opencv-Tutorial

opencv

介紹 (Introduction)

下載 (Download)

安裝 (Installer)

基本操作 (Base Operation)

視訊操作 (Camera Operation)

影像操作 (Image Operation)

色彩轉換 (Color Conversion)

影像處理 (Image Processing)

特徵擷取 (Feature Extraction)

影像切割 (Image Segmentation)

背景相減 (Background Subtraction)

物件偵測 (Object Detection)

機器學習 (Machine Learning)

其他 (Else)

Video & Image Database

GitHub : MarcWang/opencv-tutorial

continue reading OpenCV Tutorial (學習筆記)

2016年5月10日 星期二

Process API Manipulate on NodeJS v6

process.argv

執行NodeJS時帶的參數

Ex: node index.js one key=KEY

process.argv.forEach((val, index, array) => {
    console.log(`${index}: ${val}`);
    //0: node (NodeJS執行檔位置)
    //1: /Users/marc/work/node/index.js (欲執行的腳本位置)
    //2: one (第一個參數)
    //3: key=KEY (第二個參數)
});

process.version

運行NodeJS的版本,等同於 NODE_VERSION

console.log(`process.version = ${process.version}`);

process.arch

運行機器的硬體平台,’arm’, ‘ia32’, ‘x64’

console.log(`process.arch = ${process.arch}`);

process.platform

運行機器的硬體系統,’darwin’, ‘freebsd’, ‘linux’, ‘sunos’, ‘win32’

console.log(`process.platform = ${process.platform}`);

process.execPath

運行NodeJS的位置

console.log(`process.execPath = ${process.execPath}`);

process.cwd()

運行腳本的位置

console.log(`process.cwd() = ${process.cwd()}`);

process.env

取得運行的使用者環境設定process.env

console.log(`process.env.COMPUTERNAME = ${process.env.COMPUTERNAME} `);
console.log(`process.env.NUMBER_OF_PROCESSORS = ${process.env.NUMBER_OF_PROCESSORS} `);
console.log(`process.env.USERNAME = ${process.env.USERNAME} `);

process.pid

運行的Process ID

console.log(`process.pid = ${process.pid}`);

process.title

運行Process的名稱,可自訂

console.log(`process.title = ${process.title}`);

process.uptime()

程序已經運行多久時間(s)

console.log(`process.uptime() = ${process.uptime()}`);

process.hrtime()

片段程序執行時間[s,ms]

let begin = process.hrtime();
//do something
let end = process.hrtime();
console.log(`process time = ${end[0]-begin[0]} s, ${end[1]-begin[1]} ms`);

process.abort()

立即停止程序運行

process.abort();

Event uncaughtException

攔截未被抓住的錯誤事件

process.on('uncaughtException', (err) => {
    console.log(`Caught exception: ${err}`);
});

Event warning

process.on('warning', (warning) => {
    console.warn(warning.name); 
    console.warn(warning.message); 
    console.warn(warning.stack); 
});

Event beforeExit

NodeJS處理程序即將結束會觸發的事件。(非同步)

process.on('beforeExit', (code) => {
    console.log('to do something before Exit()');
});

Event exit

NodeJS處理程序結束時會觸發的事件,並回傳離開代碼

process.on('exit', (code) => {
    console.log(`About to exit with code: ${code}`);
});
continue reading Process API Manipulate on NodeJS v6