>  기사  >  웹 프론트엔드  >  javascript 이미지 처리 - Affine 변환_javascript 기술에 대한 깊은 이해

javascript 이미지 처리 - Affine 변환_javascript 기술에 대한 깊은 이해

WBOY
WBOY원래의
2016-05-16 17:43:381379검색
머리말

이전 글에서는 이미지 피라미드에 대해 설명했습니다. 이번 글에서는 아핀 변환에 대해 알아보겠습니다.

아핀?

모든 아핀 변환은 행렬(선형 변화)과 벡터(병진 변화)를 곱하여 변환될 수 있습니다.

사실 아핀은 두 사진의 변신 관계입니다.

예를 들어 아핀 변환(크기 조정, 회전, 이동 등)을 통해 이미지에 대한 작업을 수행할 수 있습니다.

수학 문제

아핀 문제를 풀기 전에 수학 문제부터 풀어볼까요.

그림과 같이 점 (x1, y1)은 원점을 기준으로 각도 a 만큼 회전하는데 이 점은 어디로 가는 걸까요?

좌표계를 극좌표계로 바꾸면 점 (x1, y1)은 (r, β)가 되고, 회전하면 (r, α β)가 됩니다.

데카르트 좌표계로 돌아가면 회전된 점은 (cos(α β) * r, sin(α β) * r)이 됩니다.

그런 다음 공식을 사용하세요 :

cos(α β)=cosαcosβ-sinαsinβ

sin(α β)=sinαcosβ cosαsinβ

원점은 (cosβ * r, sinβ * r)이므로 (x1 * cosα - y1 * sinα, x1 *로 새 점을 쉽게 얻을 수 있습니다. 시나α y1 *cosα).

여기에서 회전 변환 공식을 유도할 수 있습니다.

그러면 번역은 비교적 간단합니다. 벡터(c, d)를 추가하는 것과 같습니다.

변환 행렬 함수 구현 가져오기

보통 우리는 아핀 변환을 표현하기 위해 2 times 3 행렬을 사용합니다.

A = begin{bmatrix} a_{00} & a_{01} \ a_{10} & a_{11} end{bmatrix}_{2 times 2} B = begin{bmatrix} b_{00} \ b_{10} end{bmatrix}_{2 times 1} M = begin{bmatrix} A & B end{bmatrix} =begin{bmatrix} a_{00} & a_{01} & b_{00} \ a_{10} & a_{11} & b_{10}end{bmatrix}_{2 times 3}

여기서 A는 회전 스케일링 변환이고 B는 변환 변환입니다. 그러면 결과 T는 다음을 충족합니다.

T = A cdot begin{bmatrix}x \ yend{bmatrix}   B 또는

T = M cdot [x, y, 1]^{T}

즉, T = begin{bmatrix} a_{00}x   a_{01}y   b_{00} \ a_{10}x   a_{11}y   b_{10} end{bmatrix}

코드 복사 코드는 다음과 같습니다.

var getRotationArray2D = 함수(__angle, __x, __y){
var sin = Math.sin(__angle) || 0,
cos = Math.cos(__angle) || | 0,
y = __y || 0;

return [cos, -sin, -x,
sin, cos, -y
};


이런 방식으로 아핀 변환 행렬을 얻습니다.

물론 이 구현 자체에는 원점이 왼쪽 상단에 고정되어 있기 때문에 몇 가지 문제가 있습니다.

아핀 변환 구현


var warpAffine = function(__src, __rotArray, __dst){
(__src && __rotArray) || error(arguments.callee, IS_UNDEFINED_OR_NULL/* {line} */)
if(__src.type && __src.type === "CV_RGBA"){
var height = __src.row,
width = __src.col,
dst = __dst || new Mat(height, width, CV_RGBA),
sData = new Uint32Array(__src.buffer),
dData = new Uint32Array(dst.buffer);

var i, j, xs, ys, x, y, nowPix; >for (j = 0, nowPix = 0; j xs = __rotArray[1] * j __rotArray[2]
ys = __rotArray[4] * j __rotArray[5] ;
for(i = 0; i
if(xs > 0 && ys > 0 && xs < 너비 && ys < 높이){

y = ys | 0

dData[nowPix] = sData x]
}else{
dData[nowPix] = 4278190080; //검정색
}
}
}
}else{
error(arguments.callee, UNSPPORT_DATA_TYPE /* {line} */);
}
return
};


이 함수는 먼저 행렬 데이터를 32비트 형식으로 변환하며, 각 요소를 연산하는 것은 각 픽셀을 연산하는 것과 동일합니다.

그런 다음 모든 요소를 ​​순회하고 해당 지점에 값을 할당합니다.

효과

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.