2016-01-10

Linear Algebra: Vectors (note lại 1 số thứ về Đại số tuyến tính: Vectors)

Note lại 1 số kiến thức nền về đại số tuyến tính có liên quan đến đủ mọi thứ như SVD, PCA, optimization ... (không đầy đủ, xem thêm trong các tài liệu khác) như.

Linear Algebra MIT OCW

Search Results

Linear Algebra Done Right, by Sheldon Axler (Author), ISBN-13: 978-3319110790

Vectors


Ký pháp vector: \(\vec x = \left[ {8,6,7,5,3} \right]\)

Vector length (độ dài vector)


Với $v\in {{R}^{n}}$ chiều dài vector \(\left| {\vec v} \right| = \sqrt {\sum\nolimits_{i = 1}^n {{v_i}^2} } \)

Ví dụ:
\(\vec v = \left[ {2,2,1,3} \right]\)
\(\left| {\vec v} \right| = \sqrt {{2^2} + {2^2} + {1^2} + {3^2}}  = \sqrt {18} \)

Scalar multiplication (nhân vô hướng)


$\alpha \vec{v}=\left[ \alpha {{v}_{1}},\ \alpha {{v}_{2}},\ldots ,\alpha {{v}_{n}} \right]$

Vector space/Linear space (Không gian vector/không gian tuyến tính)


Định nghĩa

Giả sử F là một trường (field), các phần tử thuộc F gọi là vô hướng (scalar). Một không gian vector V trên trường F là một tập hợp không rỗng với 2 toán tử/phép toán cộng và nhân vector thỏa mãn các điều kiện được liệt kê sau.

Với \(\forall u,v,w \in V,\forall \alpha ,\beta  \in F\) và 1 là phần tử đơn vị của phép nhân trong trường F:

1.      Associativity of addition: \(u + (v + w) = (u + v) + w\) (tính kết hợp)
2.      Commutativity of addition: \(u + v = v + u\) (tính giao hoán)
3.      Identity element of addition: \(\exists 0 \in V,u + 0 = 0 + u = u\) (phần tử trung hòa/phần tử đơn vị với phép cộng)
4.      Inverse elements of addition: \(\exists  - u \in V,u + ( - u) = 0\) (phần tử đối/phần tử đối với phép cộng additive inverse)
5.      Identity element of scalar multiplication: \(1u = u\) (phần tử đơn vị của phép nhân trong trường F có tính chất của phần tử đơn vị với phép nhân vô hướng)
6.      Distributivity of scalar multiplication with respect to vector addition: \(\alpha (u + v) = \alpha u + \alpha v\) (tính phân phối của nhân vô hướng với phép cộng vector)
7.      Distributivity of scalar multiplication with respect to field addition: \((\alpha  + \beta )u = \alpha u + \beta u\) (tính phân phối của nhân với hướng và phép cộng trong trường số vô hướng F, lưu ý phép cộng \(\alpha  + \beta \) là phép cộng trên trường F)
8.      Compatibility of scalar multiplication with field multiplication: \(\alpha (\beta u) = (\alpha \beta )u\) (phép nhân vô hướng tương thích với phép nhân trong trường số vô hướng F, lưu ý \(\beta u\) là phép nhân vô hường trong khi đó \(\alpha \beta \) là phép nhân trên trường F, không phải là tính kết hợp của phép nhân)

Một số tính chất


Giả sử V là một không gian vector trên trường K

1.      V chỉ có một vector 0 duy nhất
2.      Với mỗi \(v \in V\) vector đối \( - v\) là duy nhất
3.      Với mỗi \(v \in V\), đối của vector đối là chính nó \( - ( - v) = v\)
4.      Với \(v \in V,k \in K\), \(kv = 0 \Leftrightarrow k = 0 \vee v = 0\)
5.      Với \(v \in V,k \in K\), \(( - p)v =  - (pv) = p( - v)\)

Basic of vector space (Cơ sở của không gian vector)


Cơ sở của không gian vector là một hệ vector độc lập tuyến tính và sinh ra không gian vector đó.

Định nghĩa

Một tập hợp \(\varepsilon  = ({\varepsilon _1},...,{\varepsilon _n})\) trong không gian vector V được gọi là cơ sở nếu

1.      \(\varepsilon  = ({\varepsilon _1},...,{\varepsilon _n})\) là một tập hợp các vector độc lập tuyến tính
2.      \(\varepsilon  = ({\varepsilon _1},...,{\varepsilon _n})\) là hệ sinh của V hay \(span(\varepsilon ) = V\)

hay

Một hệ sinh độc lập tuyến tính của một không gian vector khác { 0 } được gọi là một cơ sở của nó.
Không gian vector { 0 } không có cơ sở. Hay có thể nói, số vector trong cơ sở của không gian { 0 } bằng 0.

Linear span and basic (Hệ sinh và cơ sở)


Nếu không gian vector có một hệ sinh bao gồm m vector thì số vector của mọi hệ vector độc lập tuyến tính của nó không quá m.


Giả sử V là không gian vector trên trường K có hệ sinh \(\alpha  = ({\alpha _1},...,{\alpha _m}),{\alpha _i} \ne 0,\forall i \in \overline {1,m} \) và tồn tại một hệ \(\varepsilon  = ({\varepsilon _1},...,{\varepsilon _n})\) là hệ vector độc lập tuyến tính của V có \(n > m\).

Do \(\alpha  = ({\alpha _1},...,{\alpha _m})\) là hệ sinh của V nên \({\varepsilon _1} = {a_{11}}{\alpha _1} + {a_{12}}{\alpha _2} + ... + {a_{1m}}{\alpha _m}\).

\({\varepsilon _1} \ne 0\) nên tồn tại một \({a_{1j}} \ne 0\), không mất tính tổng quát giả sử \({a_{11}} \ne 0\).

Khi đó
\({\alpha _1} = \frac{1}{{{a_{11}}}}{\varepsilon _1} - \frac{{{a_{12}}}}{{{a_{11}}}}{\alpha _2} - ... - \frac{{{a_{1m}}}}{{{a_{11}}}}{\alpha _m}\)
Thay \({\alpha _1}\) trong hệ A bằng \({\varepsilon _1}\) được hệ \({A_1}\). Với \(\beta  \in V\), \(\beta  = {b_{11}}{\alpha _1} + {b_{12}}{\alpha _2} + ... + {b_{1m}}{\alpha _m}\), thay \({\alpha _1}\):

\(\begin{array}{l}\beta  = {b_{11}}(\frac{1}{{{a_{11}}}}{\varepsilon _1} - \frac{{{a_{12}}}}{{{a_{11}}}}{\alpha _2} - ... - \frac{{{a_{1m}}}}{{{a_{11}}}}{\alpha _m}) + {b_{12}}{\alpha _2} + ... + {b_{1m}}{\alpha _m}\\ = \frac{{{b_{11}}}}{{{a_{11}}}}{\varepsilon _1} + ({b_{12}} -  - \frac{{{a_{12}}}}{{{a_{11}}}}){\alpha _2} + ... + ({b_{1m}} - \frac{{{a_{1m}}}}{{{a_{11}}}}){\alpha _m}\end{array}\)

Hay mọi vector \(\beta  \in V\) đều biểu diễn được qua hệ \({A_1}\). Tức hệ \({A_1}\) là hệ sinh của V.

Biểu diễn \({\varepsilon _1}\) theo \({A_1}\): \({\varepsilon _2} = {a_{21}}{\varepsilon _1} + {a_{22}}{\alpha _2} + ... + {a_{2m}}{\alpha _m}\). Nếu tất cả các hệ số \({\alpha _i} = 0\) thì \({\varepsilon _2} = {a_{21}}{\varepsilon _1}\) khi đó hệ \(\varepsilon \) phụ thuộc tuyến tính. Do đó tồn tại \(\exists {a_{2j}} \ne 0,j \ne 1\), không mất tính tổng quát giả sử là \({a_{22}} \ne 0\), biểu diễn \({\alpha _2}\) với cách lập luận tương tự sẽ có hệ \({A_2}\) là hệ sinh của V.

Lần lượt thay m vector của hệ A bằng m vector đầu tiên của \(\varepsilon \), \({A_m} = ({\varepsilon _1},...,{\varepsilon _m})\) là hệ sinh của V. Theo giả thiết, \(n > m\) nên tồn tại \({\varepsilon _{m + 1}} \notin {A_m}\). Nhưng \({A_m} = ({\varepsilon _1},...,{\varepsilon _m})\) là hệ sinh của V nên \({\varepsilon _{m + 1}}\) có thể biểu diễn tuyến tính qua hệ này. Điều này trái với \(\varepsilon  = ({\varepsilon _1},...,{\varepsilon _n})\) là hệ vector độc lập tuyến tính của V.

Hệ quả: số vectơ trong hai cơ sở của một không gian vector bằng nhau.
Chứng minh trực tiếp từ định lý trên khi coi một cơ sở cũng là một hệ sinh.

Định lý 1:

Mỗi không gian vector \(V \ne \{ 0\} \) trên trường K đều có cơ sở.
Giả sử một vector \({\varepsilon _1} \ne 0 \in V\). Mỗi một vector trong không gian vector đều lập thành một hệ độc lập tuyến tính nên hệ \(\{ {\varepsilon _1}\} \) là một hệ độc lập tuyến tính.

Nếu mọi vector khác thuộc V có thể biểu diễn tuyến tính qua hệ \(\{ {\varepsilon _1}\} \) thì \(\{ {\varepsilon _1}\} \) là một cơ sở của V. Ngược lại nếu tồn tại \({\varepsilon _2}\) không biểu diễn tuyến tính theo \({\varepsilon _1}\) thì hệ \(\{ {\varepsilon _1},{\varepsilon _2}\} \) là hệ độc lập tuyến tính. Nếu hệ này không phải cơ sở thì sẽ tồn tại \({\varepsilon _3}\) không biểu diễn tuyến tính qua \(\{ {\varepsilon _1},{\varepsilon _2}\} \). Tiếp tục quá trình trên hệ cơ sở của V sẽ phải có số vector nhiều hơn. Tuy nhiên số vector này không thể quá số vector của một hệ sinh nào đó ví dụ có số vector là m. Do đó số vector của hệ độc lập tuyến tính là cơ sở của V phải dừng lại ở \(n \le m\): \(\varepsilon  = ({\varepsilon _1},...,{\varepsilon _n})\).

Hệ quả: trong không gian vector, mỗi hệ vector độc lập tuyến tính đều có thể bổ sung để tạo thành một cơ sở.

Định lý 2:

Từ một hệ sinh của không gian vector khác \(\{ 0\} \) có thể chọn ra một cơ sở.
Chứng minh tương tự, chọn \({\varepsilon _i}\) từ hệ sinh đã cho.

Vector subspace/Linear subspace (Không gian vector/tuyến tính con)


Giả sử W là một tập con của không gian vector V. Nếu W cũng là một không gian vector đối với hai phép toán đã cho trong V thì W được gọi là một không gian con của V.
Chứng minh thỏa mãn định nghĩa không gian vector. Tuy nhiên chỉ cần kiểm tra một số điều kiện ít hơn.

Định lý 1:
Giả sử W là một tập con của không gian vector V. W là một không gian con khi và chỉ khi W thỏa mãn 3 điều kiện

1.      Vector không 0 thuộc W (hay \(W \ne \emptyset \))
2.      \(x + y \in W,\forall x,y \in W\)
3.      \(ax \in W,\forall x \in W,\forall a \in K\)
(2) và (3) có thể viết dưới dạng \(ax + by \in W;\forall x,y \in W;\forall a,b \in K\)

Hệ quả:
Giả sử U, W là một không gian con của không gian vector V trên trường K khi đó giao (intersection) của hai không gian con \(U \cap W\) là một không gian con của V.

Sum of two subspaces (Tổng của hai không gian con)

Tổng của hai tập con U và W trong một không gian vector ký hiệu là \(U + W\) chứa mọi vector dạng \(u + w\) với \(u \in U\)\(w \in W\).
\(U + W = \{ u + w:u \in U,w \in W\} \)

Hệ quả:

Giả sử U, W là một không gian con của không gian vector V trên trường K khi đó \(U + W\) là một không gian con của V.

Chứng minh:

\(U + W\) chứa vector không 0, nên \(U + W \ne \emptyset \)
Giả sử có  và \(x,y \in U + W\), khi đó tồn tại \({u_1},{u_2} \in U\)\({w_1},{w_2} \in W\) sao cho \({u_1} + {w_1} = x,{u_2} + {w_2} = y\). Với hai scalar bất kỳ \(\alpha ,\beta  \in K\) xét \(\alpha x + \beta y = \alpha ({u_1} + {w_1}) + \beta ({u_2} + {w_2}) = (\alpha {u_1} + \beta {u_2}) + (\alpha {w_1} + \beta {w_2})\).

Do U, W là những không gian vector nên \((\alpha {u_1} + \beta {u_2}) \in U,(\alpha {w_1} + \beta {w_2}) \in W\). Do đó \(\alpha x + \beta y\) là tổng của một vector thuộc U và một vector thuộc V. Theo định nghĩa vector \(\alpha x + \beta y \in U + W\).

Union of two subspaces (Hội/hợp của hai không gian con)


Giả sử \({W_1},{W_2}\) là một không gian con của không gian vector V trên trường K. Khi đó \({W_1} \cup {W_2}\)  là một không gian vector khi và chỉ khi \({W_1} \subset {W_2}\) hoặc \({W_2} \subset {W_1}\).


(\( \Leftarrow \)) Giả sử \({W_2} \subset {W_1} \Rightarrow {W_1} \cup {W_2} = {W_1}\)
(\( \Rightarrow \)) Ngược lại \({W_1} \cup {W_2}\)  là một không gian vector.

Trường hợp 1: \({W_2} \subset {W_1}\), hiển nhiên không cần chứng minh

Trường hợp 2: \({W_2} \not\subset {W_1}\)

Xét \(x \in {W_1}\)\(y \in {W_2} - {W_1}\), khi đó theo định nghĩa của hội hay tập hợp \(x,y \in {W_1} \cup {W_2}\). Do \({W_1} \cup {W_2}\)  là một không gian vector nên \(x + y \in {W_1} \cup {W_2}\). Do tính chất union của hai tập hợp \({W_1} \cup {W_2}\)  nên \(x + y \in {W_1}\) hoặc \(x + y \in {W_2}\), giả sử \(x + y \in {W_1}\).

\({W_1}\)  là không gian con nên \((x + y) + ( - x) = y \in {W_1}\) trái với \(y \in {W_2} - {W_1}\). Do đó \(x + y \in {W_2}\).

Tương tự \({W_2}\)  là không gian con nên \((x + y) + ( - y) = x \in {W_2}\). Như vậy \({W_1} \subset {W_2}\)

Dimension (Số chiều của không gian vector)



Định nghĩa:

Số vector (cardinality/cardinal numbers) trong một cơ sở của một không gian vector V gọi là số chiều của V. Ký hiệu là \(di{m_k}(V)\) hay \(di{m_k}V\).

Định lý:

Trong không gian vector n chiều mọi hệ vector độc lập tuyến tính gồm n vector đều là cơ sở.
Giả sử \(dim(V) = n\)\(A = \{ {\alpha _1},{\alpha _2},...,{\alpha _n}\} \) là một hệ gồm n vector độc lập tuyến tính. Do đó có thể bổ sung vào A để tạo thành cơ sở của V. Vì \(dim(V) = n\) nên số vector của cơ sở là n không cần phải bổ sung nữa. Do đó A là một cơ sở của V.

Dimension of subspaces (Số chiều của không gian con)



Định lý 1:

Giả sử W là một không gian con của không gian vector V trên trường K.


1.      \(di{m_k}W \le di{m_k}V\)
2.      \(di{m_k}W = di{m_k}V \Leftrightarrow V = W\)

Nếu \(W = \{ 0\} \) thì \(di{m_k}W = 0 \le di{m_k}V\).

(1) Giả sử \(di{m_k}V = n\), mọi không gian vector khác \(\{ 0\} \) đều có cơ sở nên \(di{m_k}W = m > 0\) giả sử là \(\varepsilon \). Vì \(\varepsilon \) là hệ độc lập tuyến tính trong W nên cũng độc lập tuyến tính trong V, do đó không thể vượt quá số vector của một hệ sinh cũng là một cơ sở trong V gồm n vector.

(2) Suy ra từ định lý: trong không gian vector n chiều mọi hệ vector độc lập tuyến tính gồm n vector đều là cơ sở

Định lý 2:

Giả sử U, W là những không gian con của không gian vector V trên trường K.
\(di{m_k}(U + W) = di{m_k}U + di{m_k}W - di{m_k}(U \cap W)\)

Chứng minh:

Giả sử \(di{m_k}U = p,di{m_k}W = q,di{m_k}(U \cap W) = r\)
Giả sử hệ \(A = \{ {\zeta _1},{\zeta _2},...,{\zeta _r}\} \) là một cơ sở của \(U \cap W\) thì hệ này cũng độc lập tuyến tính trong U và W. Do đó có thể bổ sung hệ này để tạo thành cơ sở của U và W: \(B = \{ {\delta _1},{\delta _2},...,{\delta _{p - r}},{\zeta _1},{\zeta _2},...,{\zeta _r}\} \) là cơ sở của U và \(C = \{ {\varepsilon _1},{\varepsilon _2},...,{\varepsilon _{q - r}},{\zeta _1},{\zeta _2},...,{\zeta _r}\} \) là cơ sở của W.

Cần chứng minh rằng \(X = \{ {\delta _1},{\delta _2},...,{\delta _{p - r}},{\zeta _1},{\zeta _2},...,{\zeta _r},{\varepsilon _1},{\varepsilon _2},...,{\varepsilon _{q - r}}\} \) là một cở sở của \(U + W\).
\(\{ {\delta _1},{\delta _2},...,{\delta _{p - r}},{\zeta _1},{\zeta _2},...,{\zeta _r}\}  \subset U,\{ {\varepsilon _1},{\varepsilon _2},...,{\varepsilon _{q - r}}\}  \subset W \Rightarrow X \subset (U + W)\). Với \(\forall \alpha  = {a_1}{\delta _1} + {a_2}{\delta _2} + ... + {a_{p - r}}{\delta _{p - r}} + {b_1}{\zeta _1} + {b_2}{\zeta _2} + ... + {b_r}{\zeta _r} \in U\)\(\forall \beta  = {c_1}{\varepsilon _1} + {c_2}{\varepsilon _2} + ... + {c_{q - r}}{\varepsilon _{q - r}} + {d_1}{\zeta _1} + {d_2}{\zeta _2} + ... + {d_r}{\zeta _r} \in W\) thì \(\gamma  = \alpha  + \beta \) có thể biểu diễn tuyến tính theo X.

\(\begin{array}{l}\gamma  = \alpha  + \beta  = {a_1}{\delta _1} + {a_2}{\delta _2} + ... + {a_{p - r}}{\delta _{p - r}} + \\({b_1} + {d_1}){\zeta _1} + ({b_2} + {d_2}){\zeta _2} + ... + ({b_r} + {d_r})\zeta  + {c_1}{\varepsilon _1} + {c_2}{\varepsilon _2} + ... + {c_{q - r}}{\varepsilon _{q - r}}\end{array}\)

Nghĩa là X là một hệ sinh của \(U + W\)

Xét đẳng thức

\(\begin{array}{l}{x_1}{\delta _1} + {x_2}{\delta _2} + ... + {x_{p - r}}{\delta _{p - r}} + {y_1}{\zeta _1} + {y_2}{\zeta _2} + ... + {y_r}\zeta  + {z_1}{\varepsilon _1} + {z_2}{\varepsilon _2} + ... + {z_{q - r}}{\varepsilon _{q - r}} = 0\\ \Leftrightarrow {x_1}{\delta _1} + {x_2}{\delta _2} + ... + {x_{p - r}}{\delta _{p - r}} + {y_1}{\zeta _1} + {y_2}{\zeta _2} + ... + {y_r}\zeta  =  - {z_1}{\varepsilon _1} - {z_2}{\varepsilon _2} - ... - {z_{q - r}}{\varepsilon _{q - r}}\end{array}\)

Nếu đặt \(\mu  = {x_1}{\delta _1} + {x_2}{\delta _2} + ... + {x_{p - r}}{\delta _{p - r}} + {y_1}{\zeta _1} + {y_2}{\zeta _2} + ... + {y_r}\zeta \) thì \(\mu \) là một vector trong U, và \(\omega  =  - {z_1}{\varepsilon _1} - {z_2}{\varepsilon _2} - ... - {z_{q - r}}{\varepsilon _{q - r}} \in W\) là một vector trong W. Do dó \(\mu  = \omega  \in U \cap W\), nên có thể biểu diễn tuyến tính theo cơ sở của \(U \cap W\) là A.\( - {z_1}{\varepsilon _1} - {z_2}{\varepsilon _2} - ... - {z_{q - r}}{\varepsilon _{q - r}} = {t_1}{\zeta _1} + {t_2}{\zeta _2} + ... + {t_r}{\zeta _r} \Leftrightarrow {z_1}{\varepsilon _1} + {z_2}{\varepsilon _2} + ... + {z_{q - r}}{\varepsilon _{q - r}} + {t_1}{\zeta _1} + {t_2}{\zeta _2} + ... + {t_r}{\zeta _r} = 0\)

Do C là một hệ độc lập tuyến tính nên \({z_1}{\varepsilon _1} + {z_2}{\varepsilon _2} + ... + {z_{q - r}}{\varepsilon _{q - r}} + {t_1}{\zeta _1} + {t_2}{\zeta _2} + ... + {t_r}{\zeta _r} = 0 \Leftrightarrow {z_1} = {z_2} = ... = {z_{q - r}} = {t_1} = ... = {t_r} = 0\)
Thay \({z_i} = 0\) vào \({x_1}{\delta _1} + {x_2}{\delta _2} + ... + {x_{p - r}}{\delta _{p - r}} + {y_1}{\zeta _1} + {y_2}{\zeta _2} + ... + {y_r}\zeta  + {z_1}{\varepsilon _1} + {z_2}{\varepsilon _2} + ... + {z_{q - r}}{\varepsilon _{q - r}} = 0\) đẳng thức trở thành: \({x_1}{\delta _1} + {x_2}{\delta _2} + ... + {x_{p - r}}{\delta _{p - r}} + {y_1}{\zeta _1} + {y_2}{\zeta _2} + ... + {y_r}\zeta  = 0\). Nhưng vì B cũng là một hệ độc lập tuyến tính nên \({x_1} = {x_2} = ... = {x_{p - r}} = {y_1} = ... = {y_r} = 0\)

Kết luận X là một một cơ sở của \(U + W\).

Inner product (tích trong, tích vô hướng)


Với \(x,y \in {R^n}\) tích trong định nghĩa phép nhân (algebraic definition) hai vector (dot product hay scalar product).

\(\left( {\vec x,\vec y} \right) = \vec x \cdot \vec y = \sum\limits_{i = 1}^n {{x_i}} {y_i}\)
\(\left[ {1,3, - 5} \right] \cdot \left[ {4, - 2, - 1} \right] = 1\left( 4 \right) + 3\left( { - 2} \right) - 5\left( { - 1} \right) = 3\)

Theo định nghĩa hình học (Geometric definition) trong không gian Euclidean (Euclidean space)
\(\left( {\vec x,\vec y} \right) = \vec x \cdot \vec y = \vec x\vec y\cos \theta \) với θ là góc hợp bởi hai vector.

Euclidean space (Không gian Euclidean)


Cho V là một không gian vector trên trường R. Một tích vô hướng trên V của \(x,y \in V\) được định nghĩa là một ánh xạ \(\left\langle { \cdot , \cdot } \right\rangle :V \times V \to R\) xác định như sau:

§  Symmetry: \(\left\langle {x,y} \right\rangle  = \left\langle {y,x} \right\rangle \)
§  Additivity:  \(\left\langle {x + y,z} \right\rangle  = \left\langle {x,z} \right\rangle  + \left\langle {y,z} \right\rangle \)
§  Homogeneity: \(\left\langle {\alpha x,y} \right\rangle  = \alpha \left\langle {x,y} \right\rangle \)với \(\forall \alpha  \in R\)
§  Positivity hay positive-definiteness: (xác định dương)

\(\left\langle {x,x} \right\rangle  \ge 0\)\(\left\langle {x,x} \right\rangle  = 0 \Leftrightarrow x = 0\)
Không gian vector V trên trường số thực R có trang bị trên nó một tích vô hướng \(\left\langle {\; \cdot {\rm{,}} \cdot \;} \right\rangle \) được gọi là không gian vector Euclid/Euclidean (Euclidean space), còn ký hiệu là \(E = (V,\left\langle {\; \cdot {\rm{,}} \cdot \;} \right\rangle )\).

Tích vô hướng trên \({R^n}\) (còn gọi tích vô hướng chính tắc/chuẩn standard inner product trên \({R^n}\)), ký hiệu \(\left\langle {\; \cdot {\rm{,}} \cdot \;} \right\rangle :{R^n} \times {R^n} \to R\) định nghĩa như sau:
\(\left\langle {x,y} \right\rangle  = \sum\limits_{i = 1}^n {{x_i}} {y_i} = {x^T}y\)
Không gian vector \({R^n}\) với tích vô hướng trên \({R^n}\): \(\left( {{R^n},\left\langle {\; \cdot {\rm{,}} \cdot \;} \right\rangle } \right)\)là một không gian Euclidean

Complex vectors (Tích vô hướng trên trường số phức)

Complex conjugate (liên hợp phức)

Liên hợp phức của một số phức là một số có phần thực bằng số đó và phần ảo (imaginary part) bằng độ lớn như khác dấu (equal in magnitude but opposite in sign).
Ví dụ liên hợp phức của \(z = x + yi\)\(\overline z  = x - yi\)

Một số tính chất: cho 2 số phức z, w
\(\begin{array}{l}\overline {z + w}  = \overline z  + \overline w \\\overline {z - w}  = \overline z  - \overline w \\\overline {zw}  = \overline z \overline w \\\overline{\overline z}  = z\end{array}\)

Unitary space (Không gian unita)


Complex inner product (Tích vô hướng trên không gian vector phức)

Tổng quát với V là không gian vector trên trường \(F = R;C\), tích vô hướng của \(x,y \in V\) định nghĩa là một ánh xạ \(\left\langle {\; \cdot {\rm{,}} \cdot \;} \right\rangle :V \times V \to F\).
\(\left\langle {x,y} \right\rangle  = \sum\limits_{i = 1}^n {{x_i}} {\bar y_i}\)có các tính chất sau (dấu ngang hay phẩy là liên hợp phức – complex conjugate):

§  Conjugate symmetry: \(\left\langle {x,y} \right\rangle  = \overline {\left\langle {y,x} \right\rangle }  = \left\langle {y,x} \right\rangle \prime \)
§  Linearity in the first argument: (tuyến tính với tham số thứ 1)
\(\left\langle {\alpha x,y} \right\rangle  = \alpha \left\langle {x,y} \right\rangle \) với \(\alpha \) là scalar
\(\left\langle {x + y,z} \right\rangle  = \left\langle {x,z} \right\rangle  + \left\langle {y,z} \right\rangle \)
hay viết chung (conjugate-linear với tham số thứ 2)
\(\left\langle {x,\alpha y + \beta z} \right\rangle  = \bar \alpha \left\langle {x,y} \right\rangle  + \bar \beta \left\langle {x,z} \right\rangle \)
§  Positivity: \(\left\langle {x,x} \right\rangle  \ge 0\) \(\left\langle {x,x} \right\rangle  = 0 \Leftrightarrow x = 0\)

Không gian vector V với tích vô hướng trên \({C^n}\): \(U = \left( {{C^n},\left\langle {\; \cdot {\rm{,}} \cdot \;} \right\rangle } \right)\) gọi là không gian Unita (Unitary vector space).

Norm vector/Normalized vector (vector chuẩn, hay vector đơn vị)


Một vector chuẩn (còn gọi là vector đơn vị unit vector) là vector có độ dài bằng 1. Tất cả các vector có độ dài lớn hơn 0 đều có thể chuẩn hóa (normalize) bằng cách chia cho độ dài. Vector chuẩn của x là vector cùng hướng và có độ dài bằng 1.
$\hat{\vec{v}}=\vec{v}/\left| {\vec{v}} \right|$

Trong đó \(\left| {\vec v} \right|\) là chuẩn của \(\vec v\).
\(\left| {\vec v} \right| = \sqrt {{2^2} + {4^2} + {1^2} + {2^2}}  = 5\)
Vector $\vec{u}=\hat{\vec{v}}=\left[ 2/5,\ 4/5,\ 1/5,2/5 \right]$ là một vector chuẩn.

Vector norm (chuẩn vector xem Wolfram)


Chuẩn của một đối tượng toán học (mathematical object) là một đại lượng, một giá trị (có thể trừu tượng) mô tả chiều dài, kích thước hay phạm vi của đối tượng (extent of the object).
Thông thường nếu không đề cập đến chuẩn cụ thể nào thì chuẩn vector được coi ngầm định là chuẩn \({L_2}\)  (L2-norm).

Định nghĩa như sau:

Chuẩn của một vector x ký hiệu là \(\left\| x \right\|\) đôi khi ký hiệu là \(\left| x \right|\) (nhưng có thể nhầm là độ dài vector) được định nghĩa là một số không âm thỏa mãn các điều kiện:

1.     Positivity:\(\left\| x \right\| > 0\) khi \(x \ne 0\) và \(\left\| x \right\| = 0\) khi \(x = 0\)
2.     Homogeneity: \(\left\| {kx} \right\| = \left| k \right|\left\| x \right\|\) với mọi k vô hướng hay \(k \in R\) (tính thuần nhất)
3.     Triangle inequality: \(\left\| {x + y} \right\| \le \left\| x \right\| + \left\| y \right\|\) (bất đẳng thức tam giác)

Ngoài \({L_2}\) có các chuẩn sau gọi chung là chuẩn p (p norm) ký hiệu \({\left\| x \right\|_p}\):
\({\left\| x \right\|_p} = {\left( {\sum\nolimits_{i = 1}^n {{{\left| {{x_i}} \right|}^p}} } \right)^{1/p}}\)

Với \(p = 1,2,\infty \) sẽ có các dạng chuẩn tương ứng Manhattan, Euclidean/Euclide vàc chuẩn cực đại.

Manhattan norm (chuẩn Manhattan)


\({\left\| x \right\|_1} = \sum\limits_{i = 1}^n {\left| {{x_i}} \right|} \)
Chuẩn Manhattan còn được gọi là chuẩn Taxicab (taxi chạy theo những con đường lưới chữ nhật) hay L1-norm hay \({L_1}\). Khoảng cách tương ứng thường được gọi là khoảng cách Manhattan, khoảng cách\({L_1}\) hay khoảng cách trong thành phố.

Với hay điểm trong không gian Euclid với hệ trục tọa độ Descartes, đại lượng khoảng cách \({L_1}\) này được tính bằng tổng chiều dài của hình chiếu của đường thẳng nối hai điểm này trong hệ trục tọa độ.

Các đường đỏ, xanh, vàng thể hiện khoảng cách Manhattan với cùng độ dài là 12. Đường xanh lục biểu diễn khoảng cách Euclid (Euclidean distance) chiều dài \(6\sqrt 2 \).

Euclidean norm (chuẩn Euclidean/Euclid)


\({\left\| x \right\|_2} = {\left( {\sum\nolimits_{i = 1}^n {{{\left| {{x_i}} \right|}^2}} } \right)^{1/2}} = \sqrt {\sum\nolimits_{i = 1}^n {{x_i}^2} }  = \sqrt {({x_1}^2 + {x_2}^2 + ... + {x_n}^2} \)

Dạng chuẩn Euclid tương ứng còn gọi là chuẩn \({L_2}\) còn gọi là độ lớn hay chiều dài vector (the magnitude of a vector).

Infinity norm (chuẩn vô cực)


\({x_{max}} = \mathop {\max }\limits_i \left| {{x_i}} \right| = {\rm{max}}\left( {\left| {{x_1}} \right|,\left| {{x_2}} \right|, \ldots ,\left| {{x_n}} \right|} \right)\)
Ví dụ về vòng tròn đơn vị (unit circle) tương ứng với các chuẩn vô cực, Euclid và Manhattan trong không gian 2 chiều (vòng tròn đơn vị là tập hợp tất cả các điểm trong không gian có chuẩn bằng 1)


Hình: Illustrations of unit circles in different norms Wikipedia

Sum and direct sum (tổng và tổng trực tiếp)


Cho \(V\)là không gian vector trên trường \(K\) và \(U,W\) là không gia con của \(V\). Định nghĩa tổng của \(U\) và \(W\) ký hiệu là \(U + W\) là một tập con của \(V\) chứa mọi phần tử \(u + w\) với \(u \in U\) và \(w \in W\). Tổng \(U + W\) cũng là một không gian vector.

Định nghĩa \(V\) là tổng trực tiếp của \(U\) và \(W\) ký hiệu là \(U \oplus W\) nếu mọi \(v \in V\) tồn tại duy nhất các phần tử \(u \in U\) và \(w \in W\) sao cho \(v = u + w\).

Định lý:

Cho \(V\)là không gian vector trên trường \(K\) và \(U,W\) là không gia con của \(V\). Nếu \(U + W = V\) và nếu \(U \cap W = \{ 0\} \) thì \(V\) là tổng trực tiếp của \(U\) và \(W\).

Nếu \(V\) là tổng trực tiếp của \(U\) và \(W\) thì \(dimV = dimU + dimW\).

Orthogonality (tính trực giao)


Hai vector gọi là trực giao nên tích vô hướng bằng zero. Trong không gian hai chiều có thể nói góc giữa hai vector là 90 độ ký hiệu \(\left\langle {u,v} \right\rangle  = 0\) hay \(u \bot v\).
\(\left[ {2,1, - 2,4} \right] \cdot \left[ {3, - 6,4,2} \right] = 0\)

Vector \(x \in E\) gọi là trực giao với tập \(A \subset E\) nếu \(x\) trực giao với mọi vector của \(A\). Ký hiệu là \(x \bot A.\)

Định lý:

Một hệ trực giao không chứa vector 0 là hệ độc lập tuyến tính.

Orthonormal vectors (các vector chuẩn trực giao hay trực chuẩn)


Hệ các vector chuẩn hay vector đơn vị trực giao với nhau được gọi là hệ trực chuẩn.

Orthonormal basis (cơ sở trực chuẩn)


Một cơ sở mà là hệ trực chuẩn được gọi là cơ sở trực chuẩn.

Gram-Schmidt orthogonalization/orthonormalization process (trực giao/chuẩn hóa Gram-Schmidt)


Định lý:
Cho hệ vector độc lập tuyến tính \({a_1},{a_2},...,{a_n}(n \ge 2)\) trong không gian vector Euclidean. Khi đó trong E tồn tại họ vector độc lập tuyến tính \({b_1},{b_2},...,{b_n}\) thỏa mãn:
§  Hệ \({a_1},{a_2},...,{a_n}\) có thể biểu thị tuyến tính qua \({b_1},{b_2},...,{b_n}\).
§  Hệ \({b_1},{b_2},...,{b_n}\) có thể biểu thị tuyến tính qua \({a_1},{a_2},...,{a_n}\).

§  Hệ \({b_1},{b_2},...,{b_n}\)là hệ trực giao.

Trực chuẩn hóa Gram-Schmidt là một phương pháp biết đổi một tập hợp các vector thành một tập các vector trực chuẩn (orthonormal vectors). Phương pháp này thực hiện chuẩn hóa một vector đầu tiên và tìm cách viết (lặp đi lặp lại) các vector còn lại bằng các trừ chính nó với tích của các vector đã chuẩn hóa.

Giả sử hệ S gồm n vector \(S = \left\{ {{u_1},{u_2}, \ldots ,{u_n}} \right\}\)

§  Đặt \({v_1} = \frac{{{u_1}}}{{\left\| {{u_1}} \right\|}}\)
§  Tính \(\overline {{v_k}} \) bằng công thức \(\overline {{v_k}}  = {u_k} - \sum\limits_{i = 1}^{k - 1} {\left\langle {{u_k},{v_i}} \right\rangle } .{v_i}\) với \(k = 2, \ldots ,n\)
§  Tính \({v_k} = \frac{{\overline {{v_k}} }}{{\left\| {\overline {{v_k}} } \right\|}}\)

Theo đó
\(\overline {{v_2}}  = {u_2} - \left\langle {{u_2},{v_1}} \right\rangle .{v_1}\)
\(\overline {{v_3}}  = {u_3} - \left\langle {{u_3},{v_1}} \right\rangle .{v_1} - \left\langle {{u_3},{v_2}} \right\rangle .{v_2}\)
\(\overline {{v_4}}  = {u_4} - \left\langle {{u_4},{v_1}} \right\rangle .{v_1} - \left\langle {{u_4},{v_2}} \right\rangle .{v_2} - \left\langle {{u_4},{v_3}} \right\rangle .{v_3}\)

Ví dụ: (dùng WolframAlpha với input “Gram-Schmidt {{1,1,1},{-1,1,1},{1,2,1}}” hay “orthogonalize {{1,1,1},{-1,1,1},{1,2,1}}”)

Xét hệ 3 vector độc lập trong \({R^3}\)\({u_1} = \left[ {1,1,1} \right],{u_2} = \left[ { - 1,1,1} \right],{u_3} = \left[ {1,2,1} \right]\). Trực chuẩn hóa Gram-Schmidt \(S = \left\{ {{u_1},{u_2},{u_3}} \right\}\)



\({v_1} = \frac{{{u_1}}}{{\left\| {{u_1}} \right\|}} = \left[ {1/\sqrt 3 ,1/\sqrt 3 ,1/\sqrt 3 } \right]\)
\(\overline {{v_2}}  = {u_2} - \left\langle {{u_2},{v_1}} \right\rangle .{v_1} = \left[ { - 1,1,1} \right] - \left( {1/\sqrt 3 } \right)\left[ {1/\sqrt 3 ,1/\sqrt 3 ,1/\sqrt 3 } \right] = \left[ { - 4/3,2/3,2/3} \right]\)
\({v_2} = \frac{{\overline {{v_2}} }}{{\left\| {\overline {{v_2}} } \right\|}} = \left[ { - 2/\sqrt 6 ,1/\sqrt 6 ,1/\sqrt 6 } \right]\)
\(\overline {{v_3}}  = {u_3} - \left\langle {{u_3},{v_1}} \right\rangle .{v_1} - \left\langle {{u_3},{v_2}} \right\rangle .{v_2} = \left[ {0,1/2, - 1/2} \right]\)
\({v_3} = \frac{{\overline {{v_3}} }}{{\left\| {\overline {{v_3}} } \right\|}} = \left( {0,1/\sqrt 2 , - 1/\sqrt 2 } \right)\)


${{v}_{1}}=\left[ \frac{1}{\sqrt{3}},\frac{1}{\sqrt{3}},\frac{1}{\sqrt{3}} \right],{{v}_{2}}=\left[ \frac{-2}{\sqrt{6}},\frac{1}{\sqrt{6}},\frac{1}{\sqrt{6}} \right],{{v}_{3}}=\left[ 0,\frac{1}{\sqrt{2}},\frac{-1}{\sqrt{2}} \right]$

Hệ \(\left\{ {{v_1},{v_2},{v_3}} \right\}\) là hệ trực chuẩn hóa của \(S = \left\{ {{u_1},{u_2},{u_3}} \right\}\)


Ví dụ:
Mở rộng hệ trực giao gồm hai vector \({u_1} = (1,1,1,2),{u_2} = (1,2,3, - 3)\) thành một cơ sở trực chuẩn của \({R^4}\).

Bước 1: bổ sung thêm hai vector \({u_3},{u_4}\) để hệ \({u_1},{u_2},{u_3},{u_4}\) là hệ độc lập tuyến tính, đơn giản có thể chọn có thể chọn \({u_3} = {e_3} = (0,0,1,0)\) và  \({u_4} = {e_4} = (0,0,0,1)\).
Bước 2: Áp dụng phương pháp trực chuẩn hóa Gram-Schmidt như trên để tìm ra cơ sở trực chuẩn của \({R^4}\).

Orthogonal complement (phần bù trực giao)/Orthogonal projection (phép chiếu trực giao)


Cho \(V\) là không gian con (subspace) của \({R^n}\), phần bù trực giao (orthogonal complement) của \(V\)ký hiệu là \({V^ \bot }\)là tập hợp chứa tất cả các vector trực giao (hay vuông góc perpendicular) với mọi vector của \(V\)\({V^ \bot } = \{ x \in {R^n}|x \bot V\} \)\({V^ \bot }\) cũng là một không giao con của \({R^n}\), còn gọi là không gian con bù trực giao của \(V\).
\(V\)và \({V^ \bot }\) hợp thành \({R^n}\)\(x \in {R^n}\) đều có thể biểu diễn duy nhất dưới dạng \(x = {x_1} + {x_2}\)với \({x_1} \in V\) và \({x_2} \in {V^ \bot }\). Dạng biểu diễn này gọi là phân tích trực giao (orthogonal decomposition) của \(x\). Khi đó, \({x_1}\) và \({x_2}\) là kết quả của các phép chiếu trực giao/trực phương (orthogonal projection) của \(x\) lên các không gian con \(V\)và \({V^ \bot }\)\({R^n}\) được gọi là tổng trực tiếp (direct sum) của \(V\)và \({V^ \bot }\), ký hiệu là \({R^n} = V \oplus {V^ \bot }\).

Định lý:

Giả sử \(U,W\)là các không gian con của \({R^n}\). Khi đó:
\({({U^ \bot })^ \bot } = U\)
\({(U + W)^ \bot } = {U^ \bot } \cap {W^ \bot }\)
\({(U \cap W)^ \bot } = {U^ \bot } + {W^ \bot }\)
\({R^n} = U \oplus {U^ \bot }\)

Một phép biến đổi tuyến tính \(P\) gọi là orthogonal projector lên \(V\) (orthogonal projector onto \(V\)) nếu \(\forall x \in {R^n}\)  thỏa mãn \(Px \in V\) và \(x - Px \in {V^ \bot }\).

Projection onto a subspace (chiếu lên không gian con)


Cho \(V\) là không gian con của \({R^n}\) và \(x \in {R^n}\). Vector chiếu/hình chiếu (vector projection) của \(x\) lên \(V\) là vector \(v \in V\) sao cho \(x - v\) trực giao với \(V\).  Khi đó, ta gọi vector \(x - v\) là vector độ cao từ \(x\) đến \(V\).

Nhận xét:
§  Nếu \(S = \{ {e_1},{e_2},...,{e_m}\} \)là một cơ sở trực chuẩn (orthonormal basis) trong \(V\) thì vector chiếu \(v\) của \(x\) được xác định như sau: \(v = pro{j_V}(x) = \left\langle {x,{e_1}} \right\rangle {e_1} + ... + \left\langle {x,{e_m}} \right\rangle {e_m}\)
§  Vector độ cao có độ dài ngắn nhất trong tất cả các vector nối \(x\) tới \(V\).

Ví dụ:

Hình chiếu trực giao/phương của \(v = ( - 1,4,3)\) lên không gian con W của \({R^3}\) tạo bởi các vector trực giao \({w_1} = (1,1,0)\) và \({w_2} = ( - 1,1,0)\).

Xét \(pro{j_W}v = \tilde w = \frac{{\left\langle {v,{w_1}} \right\rangle }}{{\left\langle {{w_1},{w_1}} \right\rangle }}{w_1} + \frac{{\left\langle {v,{w_2}} \right\rangle }}{{\left\langle {{w_2},{w_2}} \right\rangle }}{w_2} = \frac{3}{2}\left[ {\begin{array}{*{20}{c}}1\\1\\0\end{array}} \right] + \frac{5}{2}\left[ {\begin{array}{*{20}{c}}{ - 1}\\1\\0\end{array}} \right] = \left[ {\begin{array}{*{20}{c}}{ - 1}\\4\\0\end{array}} \right]\).

Vector \(\tilde w\) là projection vector thuộc không gian con W.
Vector \(v - \tilde w = \left[ {\begin{array}{*{20}{c}}{ - 1}\\4\\3\end{array}} \right] - \left[ {\begin{array}{*{20}{c}}{ - 1}\\4\\0\end{array}} \right] = \left[ {\begin{array}{*{20}{c}}0\\0\\3\end{array}} \right]\) trực giao với W vì trực giao với \({w_1}\) và \({w_2}\).
Orthogonal decomposition của v theo \(W\) và \({W^ \bot }\) là:
\(\left[ {\begin{array}{*{20}{c}}{ - 1}\\4\\3\end{array}} \right] = \left[ {\begin{array}{*{20}{c}}{ - 1}\\4\\0\end{array}} \right] + \left[ {\begin{array}{*{20}{c}}0\\0\\3\end{array}} \right]\)


2015-12-21

OpenCV quick start

Lâu ngày có dịp dùng OpenCV. Tính ra chỉ lúc học ĐH là xài nhiều sau đó dùng thêm 1 số dịp nữa là thôi. Kể từ lần cuối viết theo C style của version 1, hầu như chẳng đụng tới nó. Sẵn tiện coi thử có gì mới sau gần 10 năm.

Phiên bản giờ là OpenCV 3.1 ngày 2015-12-21, tuy nhiên do chưa đụng tới lâu nên xem thử trước version 2 là OpenCV 2.4.12 ngày 2015-07-30. Download bản dùng cho Windows, code C/C++ xài Visual Studio 2013/Windows nói chung khá là OK. Change logs thì có ở đây. So với những gì còn nhớ thì cách viết chuyển qua C++ hết, để NS, chuyển struct thành class :D. Nói chung ok, có vẻ dễ xài hơn.

Đầu tiên thì setup, sau khi download về và install vào đâu đó thường mình để chung 1 đám trong D:\dev, giả sử là D:\dev\opencv-2.4.12.



Setup

Tạo environment variable để dễ sử dụng cho configuration tên là OPENCV_DIR.
Chọn View Other Windows Property Manager Debug | x64.

Chọn Microsoft.Cpp.x64.user Properties, thêm user macro OPENCV_DIR, set macro là environment variable.

Thêm OpenCV vào project, tạo environment variable OPENCV_DIR dùng global property page
Với Visual Studio 2008 (vc10): Tools Options Projects and Solutions VC++ Directories.

Thêm đường dẫn bin (chứa các dll của OpenCV) vào PATH Control Panel System Advanced system settings Advanced Tab Environment variables... Tuy nhiên các này không tốt lắm, tốt nhất là thêm bin theo project khi debug.

Nếu theo project trong Project Properties Debugging Environment.
Ví dụ: OpenCV

PATH=$(OPENCV_DIR)\x64\vc12\bin%3b$(PATH)

Ví dụ: Qt + OpenCV

PATH=$(QTDIR)\bin%3b$(OPENCV_DIR)\x64\vc12\bin%3b$(PATH)

Thêm Project Properties Configuration Properties C/C++ General Additional Include Directories

OpenCV

.;$(OPENCV_DIR)\include;%(AdditionalIncludeDirectories)

Với Qt + OpenCV

.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;$(OPENCV_DIR)\include;%(AdditionalIncludeDirectories)

Thêm Project Properties Configuration Properties Linker General Additional Library Directories

$(OPENCV_DIR)\x64\vc12\lib;

Thêm Project Properties Configuration Properties Linker Input Additional Dependencies
opencv_[xxx]2412[d].lib với 2412 là version và d cho debug configuration.

opencv_calib3d2412d.lib
opencv_contrib2412d.lib
opencv_core2412d.lib
opencv_features2d2412d.lib
opencv_flann2412d.lib
opencv_gpu2412d.lib
opencv_highgui2412d.lib
opencv_imgproc2412d.lib
opencv_legacy2412d.lib
opencv_ml2412d.lib
opencv_nonfree2412d.lib
opencv_objdetect2412d.lib
opencv_ocl2412d.lib
opencv_photo2412d.lib
opencv_stitching2412d.lib
opencv_superres2412d.lib
opencv_ts2412d.lib
opencv_video2412d.lib
opencv_videostab2412d.lib

Showing Image

OK ví dụ đơn giản lấy ví dụ của OpenCV thử.

#include <opencv/cv.h> 
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv/highgui.h> 

using namespace std;

int main(int argcconst char** argv)
{
     cv::Mat image;
     cv::String fileName = "demo.jpg";

     if (argc == 2) {
        fileName = argv[1];     // Image path from args
     }

     if (fileName.empty()) {
        cout << " Usage: display_image /path/to/image" << endl;
        return -1;
     }
     else {
        image = cv::imread(fileName);
        if (image.empty()) {
           cout << "Could not open or find the image" << endl;
           return -1;
        }
        else {
           cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE);  // Create a window for display.
           cv::imshow("Display window", image);               // Show our image inside it.

           cv::waitKey(0);                                 // Wait for a keystroke in the window
        }
     }
}

Các ví dụ có thể tìm tại OpenCV tutorials và module xử lý ảnh Image Processing

Dùng với Qt

Chuyển giữa OpenCV::Mat và Qt::QImage Convert between cv::mat and Qimage correctly
xem chi tiết tại Qt and OpenCV.

OpenCV dùng mặc định BGR thay cho RGB. Để hiển thị ảnh grayscale dùng QImage::Format_Grayscale8 hoặc dùng QImage::Format_RGB888 cho ảnh 8UC3.

//---------------------------------------------------------------------------
// Convert cv::Mat to QImage without copy(share the same buffer)
//---------------------------------------------------------------------------
// The trap at here is mat.step, the buffer of the cv::Mat may do some padding(factor of 4)
// on each row for the sake of speed. If you just wrote
// QImage(mat.data, mat.cols, mat.rows, format);

//---------------------------------------------------------------------------
// Convert the channels from RGB to BGR
//---------------------------------------------------------------------------
// The default channels of the openCV is BGR but the QImage is RGB,
// that means you need to convert the channels from RGB to BGR when
// convert between three channels image and vice versa.In QImage,
// you could call "rgbSwapped()";
// In cv::Mat, you could call cv::cvtColor to convert the channels.
// cvtColor(col, rgb,cv::COLOR_BGR2RGB);
auto image = QImage(mat.data, mat.cols, mat.rows,
     mat.step, QImage::Format_RGB888)
     .rgbSwapped();

//---------------------------------------------------------------------------
// Convert QImage to cv::Mat without copy(share the same buffer)
//---------------------------------------------------------------------------
//mat = cv::Mat(img.height(), img.width(),
//   format, img.bits(), img.bytesPerLine());

//---------------------------------------------------------------------------
// Convert cv::Mat to QImage by copy
//---------------------------------------------------------------------------
//img = QImage(mat.data, mat.cols, mat.rows,
//   mat.step, format).copy();

Đổi colorspace cho pixel

Để đổi colorspace cho single pixel, OpenCV ko expose method, copy struct conversion từ source code tại OpenCV Github nhưng nhanh nhất là chuyển sang Mat 1x1 pixel.
Lưu ý: OpenCV xài HSV/HSB với ảnh 8 bit range là (180-255-255) so với thông thường (360-100-100) để match với range 0-255.

Xem phần RGB / HSV (CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB)
8-bit images
$V  \leftarrow 255 V, S  \leftarrow 255 S, H  \leftarrow H/2  \text{(to fit to 0 to 255)}$

cv::Scalar colorBGR2HSV(const cv::Scalar& bgrClr) {
     // cv::Scalar.val[0-2] used
     cv::Mat bgr(1, 1, CV_8UC3);
     bgr.setTo(bgrClr);

     cv::Mat hsv;
     cv::cvtColor(bgr, hsv, cv::COLOR_BGR2HSV);

     auto clr = hsv.atVec3b>(cv::Point(0, 0));
     return cv::Scalar(clr.val[0], clr.val[1], clr.val[2]);
}

cv::Scalar colorBGR2Lab(const cv::Scalar& bgrClr) {
     // cv::Scalar.val[0-2] used
     cv::Mat bgr(1, 1, CV_8UC3);
     bgr.setTo(bgrClr);

     cv::Mat lab;
     cv::cvtColor(bgr, lab, cv::COLOR_BGR2Lab);

     auto clr = lab.atVec3b>(cv::Point(0, 0));
     return cv::Scalar(clr.val[0], clr.val[1], clr.val[2]);
}

cv::Scalar colorHSV2BGR(const cv::Scalar& hsvClr) {
     // cv::Scalar.val[0-2] used
     cv::Mat hsv(1, 1, CV_8UC3);
     hsv.setTo(hsvClr);

     cv::Mat bgr;
     cv::cvtColor(hsv, bgr, cv::COLOR_HSV2BGR);

     auto clr = bgr.atVec3b>(cv::Point(0, 0));
     return cv::Scalar(clr.val[0], clr.val[1], clr.val[2]);
}

cv::Scalar colorHSV2Lab(const cv::Scalar& hsvClr) {
     // cv::Scalar.val[0-2] used
     cv::Mat hsv(1, 1, CV_8UC3);
     hsv.setTo(hsvClr);

     cv::Mat bgr, lab;
     cv::cvtColor(hsv, bgr, cv::COLOR_HSV2BGR);
     cv::cvtColor(bgr, lab, cv::COLOR_BGR2Lab);

     auto clr = lab.atVec3b>(cv::Point(0, 0));
     return cv::Scalar(clr.val[0], clr.val[1], clr.val[2]);
}

Xác định màu của image, findContours

Để xác định object có màu xác định thông thường sẽ dùng threshold binrary với mask là lower/upper color.

Range để xác định một số màu cơ bản

void initializeRanges() {

 // Red lower 0°-28° (0-360)
 colorRanges.push_back(ColorRange(ColorType::Red,
  cv::Scalar(0, 27, 35), cv::Scalar(14, 255, 255)));

 // Brown 28°-40° (0-360)
 colorRanges.push_back(ColorRange(ColorType::Brown,
  cv::Scalar(14, 27, 35), cv::Scalar(20, 255, 255)));

 // Orange 40°-46° (0-360)
 colorRanges.push_back(ColorRange(ColorType::Orange,
  cv::Scalar(20, 27, 35), cv::Scalar(23, 255, 255)));

 // Yellow 46°-64° (0-360)
 colorRanges.push_back(ColorRange(ColorType::Yellow,
  cv::Scalar(23, 27, 35), cv::Scalar(34, 255, 255)));

 // Green 64°-146° (0-360)
 colorRanges.push_back(ColorRange(ColorType::Green,
  cv::Scalar(34, 27, 35), cv::Scalar(73, 255, 255)));

 // Aqua 146°-204° (0-360)
 colorRanges.push_back(ColorRange(ColorType::Aqua,
  cv::Scalar(73, 27, 35), cv::Scalar(102, 255, 255)));

 // Aqua-Blue, Blue 204°-254° (0-360)
 colorRanges.push_back(ColorRange(ColorType::Blue,
  cv::Scalar(102, 27, 35), cv::Scalar(127, 255, 255)));

 // Magenta 254°-298° (0-360)
 colorRanges.push_back(ColorRange(ColorType::Magenta,
  cv::Scalar(127, 27, 35), cv::Scalar(149, 255, 255)));

 // Pink 298°-350° (0-360)
 colorRanges.push_back(ColorRange(ColorType::Pink,
  cv::Scalar(149, 27, 37), cv::Scalar(175, 255, 255)));

 // Red upper 350°-360° (0-360)
 colorRanges.push_back(ColorRange(ColorType::Red,
  cv::Scalar(175, 27, 35), cv::Scalar(180, 255, 255)));

 // Black
 colorRanges.push_back(ColorRange(ColorType::Black,
  cv::Scalar(0, 0, 0), cv::Scalar(180, 255, 35)));

 // White (not blue) hue 0°-170° (0-360) & 230°-360° (0-360)
 colorRanges.push_back(ColorRange(ColorType::White,
  cv::Scalar(0, 0, 190), cv::Scalar(85, 27, 255)));
 colorRanges.push_back(ColorRange(ColorType::White,
  cv::Scalar(115, 0, 190), cv::Scalar(180, 27, 255)));

 colorRanges.push_back(ColorRange(ColorType::Blue,
  cv::Scalar(85, 0, 190), cv::Scalar(115, 27, 255)));
};

Xác định vùng theo specific color

// Threshold the HSV image to get only specific colors
cv::Mat mask, blurred, thresholded;
cv::inRange(hsv, lower, upper, mask);

cv::GaussianBlur(mask, blurred, cv::Size(9, 9), 5, 5);

// Separate out regions of an image corresponding to objects which we want to analyze. 
// This separation is based on the variation of intensity 
// between the object pixels and the background pixels.
cv::threshold(blurred, thresholded, 120, 255, CV_THRESH_BINARY);

// MORPH_RECT vs MORPH_CROSS vs MORPH_ELLIPSE
cv::Mat strEl = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10, 10));

// Morphological opening (remove small objects from the foreground)
// Open dilate(erode(src, element))
//cv::erode(thresholded, thresholded, strEl);
//cv::dilate(thresholded, thresholded, strEl);
cv::morphologyEx(thresholded, thresholded, cv::MORPH_OPEN, strEl);

// Morphological closing (fill small holes in the foreground)
// Close erode(dilate(src, element))
//cv::dilate(thresholded, thresholded, strEl);
//cv::erode(thresholded, thresholded, strEl);
cv::morphologyEx(thresholded, thresholded, cv::MORPH_CLOSE, strEl);

cv::vector<cv::vector<cv::Point> > contours;
cv::vector<cv::Vec4i> hierarchy;

// CV_RETR_EXTERNAL/CV_RETR_LIST instead of CV_RETR_TREE 
// @see http://stackoverflow.com/questions/8830619/difference-between-cv-retr-list-cv-retr-tree-cv-retr-external
// Documentation http://opencv.itseez.com/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?#findcontours
// CV_RETR_EXTERNAL gives "outer" contours, so if you have (say) one contour enclosing another 
// (like concentric circles), only the outermost is given.
cv::findContours(thresholded, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);

//cv::RNG rng;
//cv::Mat mat = thresholded.clone();
//for (int i = 0; i < contours.size(); i++) {
// auto clr = cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
// cv::drawContours(mat, contours, i, clr, 1, 8, hierarchy, 0, cv::Point());
//}

Color difference

Chuyển qua L*a*b scale và dùng CIE Delta E 1976 algorithm hay CIE Delta E 2000.
Code của algorithm này như sau:

double deg2rad(double deg) {
 return (deg * (M_PI / 180.0));
}

double rad2deg(double rad) {
 return ((180.0 / M_PI) * rad);
}

// Computes the difference between two BGR colors by converting them to 
// the L*a*b scale BGR/CIE (CV_BGR2Lab) and comparing them using the 
// CIE76 algorithm http://en.wikipedia.org/wiki/Color_difference#CIE76
// The 1976 formula is the first color-difference formula that related 
// a measured to a known set of CIELAB coordinates. This formula has been 
// succeeded by the 1994 and 2000 formulas because the CIELAB space 
// turned out to be not as perceptually uniform as intended, especially in 
// the saturated regions. This means that this formula rates these 
// colors too highly as opposed to other colors.
// Lab, Delta E (standard Euclidean distance) sqrt(L² + a² + b²)
// CIE Delta E 1976
// JND: ~2.3
double deltaE1976(const cv::Scalar& lab1, const cv::Scalar& lab2)
{
 // RGB/CIE L*a*b*
 // 8-bit images: L ← L ∗ 255 / 100, a ← a + 128, b ← b + 128
 auto dL = lab1.val[0] - lab2.val[0];
 // Covert dL back CIE L*a*b*
 dL = dL * 100 / 255;

 auto da = lab1.val[1] - lab2.val[1];
 auto db = lab1.val[2] - lab2.val[2];

 return cv::sqrt(dL * dL + da * da + db * db);
}

// http://svn.int64.org/viewvc/int64/colors/colors.js
// http://www.ece.rochester.edu/~gsharma/ciede2000/
double deltaE2000(const cv::Scalar& lab1, const cv::Scalar& lab2) {

 // RGB/CIE L*a*b*
 // 8-bit images: L ← L ∗ 255 / 100, a ← a + 128, b ← b + 128
 auto x = lab1;
 auto y = lab2;

 /*
 * "For these and all other numerical/graphical delta E00 values
 * reported in this article, we set the parametric weighting factors
 * to unity(i.e., kL = kC = kH = 1.0)." (Page 27).
 */
 const double kL = 1.0, kC = 1.0, kH = 1.0;
 const double deg360InRad = deg2rad(360.0);
 const double deg180InRad = deg2rad(180.0);
 const double pow25To7 = 6103515625.0; /* pow(25, 7) */

 /*
 * Step 1
 */
 /* Equation 2 */
 double C1 = sqrt((x.val[1] * x.val[1]) + (x.val[2] * x.val[2]));
 double C2 = sqrt((y.val[1] * y.val[1]) + (y.val[2] * y.val[2]));

 /* Equation 3 */
 double barC = (C1 + C2) / 2.0;

 /* Equation 4 */
 double G = 0.5 * (1 - sqrt(pow(barC, 7) / (pow(barC, 7) + pow25To7)));

 /* Equation 5 */
 double a1Prime = (1.0 + G) * x.val[1];
 double a2Prime = (1.0 + G) * y.val[1];

 /* Equation 6 */
 double CPrime1 = sqrt((a1Prime * a1Prime) + (x.val[2] * x.val[2]));
 double CPrime2 = sqrt((a2Prime * a2Prime) + (y.val[2] * y.val[2]));

 /* Equation 7 */
 double hPrime1;
 if (x.val[2] == 0 && a1Prime == 0) {
  hPrime1 = 0.0;
 }
 else {
  hPrime1 = atan2(x.val[2], a1Prime);
  /*
  * This must be converted to a hue angle in degrees between 0
  * and 360 by addition of 2􏰏 to negative hue angles.
  */
  if (hPrime1 < 0){
   hPrime1 += deg360InRad;
  }
 }

 double hPrime2;
 if (y.val[2] == 0 && a2Prime == 0) {
  hPrime2 = 0.0;
 }
 else {
  hPrime2 = atan2(y.val[2], a2Prime);
  /*
  * This must be converted to a hue angle in degrees between 0
  * and 360 by addition of 2 to negative hue angles.
  */
  if (hPrime2 < 0){
   hPrime2 += deg360InRad;
  }
 }

 /*
 * Step 2
 */
 /* Equation 8 */
 double deltaLPrime = y.val[0] - x.val[0];

 /* Equation 9 */
 double deltaCPrime = CPrime2 - CPrime1;

 /* Equation 10 */
 double deltahPrime;
 double CPrimeProduct = CPrime1 * CPrime2;

 if (CPrimeProduct == 0) {
  deltahPrime = 0;
 }
 else {
  /* Avoid the fabs() call */
  deltahPrime = hPrime2 - hPrime1;
  if (deltahPrime < -deg180InRad) {
   deltahPrime += deg360InRad;
  }
  else if (deltahPrime > deg180InRad) {
   deltahPrime -= deg360InRad;
  }
 }
 /* Equation 11 */
 double deltaHPrime = 2.0 * sqrt(CPrimeProduct) *
  sin(deltahPrime / 2.0);

 /*
 * Step 3
 */
 /* Equation 12 */
 double barLPrime = (x.val[0] + y.val[0]) / 2.0;

 /* Equation 13 */
 double barCPrime = (CPrime1 + CPrime2) / 2.0;

 /* Equation 14 */
 double barhPrime, hPrimeSum = hPrime1 + hPrime2;

 if (CPrime1 * CPrime2 == 0) {
  barhPrime = hPrimeSum;
 }
 else {
  if (fabs(hPrime1 - hPrime2) <= deg180InRad) {
   barhPrime = hPrimeSum / 2.0;
  }
  else {
   if (hPrimeSum < deg360InRad) {
    barhPrime = (hPrimeSum + deg360InRad) / 2.0;
   }
   else {
    barhPrime = (hPrimeSum - deg360InRad) / 2.0;
   }
  }
 }

 /* Equation 15 */
 double T = 1.0 - (0.17 * cos(barhPrime - deg2rad(30.0))) +
  (0.24 * cos(2.0 * barhPrime)) +
  (0.32 * cos((3.0 * barhPrime) + deg2rad(6.0))) -
  (0.20 * cos((4.0 * barhPrime) - deg2rad(63.0)));

 /* Equation 16 */
 double deltaTheta = deg2rad(30.0) *
  exp(-pow((barhPrime - deg2rad(275.0)) / deg2rad(25.0), 2.0));

 /* Equation 17 */
 double RC = 2.0 * sqrt(pow(barCPrime, 7.0) /
  (pow(barCPrime, 7.0) + pow25To7));

 /* Equation 18 */
 double SL = 1 + ((0.015 * pow(barLPrime - 50.0, 2.0)) /
  sqrt(20 + pow(barLPrime - 50.0, 2.0)));

 /* Equation 19 */
 double SC = 1 + (0.045 * barCPrime);

 /* Equation 20 */
 double SH = 1 + (0.015 * barCPrime * T);

 /* Equation 21 */
 double RT = (-sin(2.0 * deltaTheta)) * RC;

 /* Equation 22 */
 double deltaE = sqrt(
  pow(deltaLPrime / (kL * SL), 2.0) +
  pow(deltaCPrime / (kC * SC), 2.0) +
  pow(deltaHPrime / (kH * SH), 2.0) +
  (RT * (deltaCPrime / (kC * SC)) * (deltaHPrime / (kH * SH))));

 return (deltaE);
}