2014-10-02 2 views
4

OpenCV의 warpPerspective에서 올바르게 작동하는 3x3 호모 그래피 매트릭스가 있지만 성능상의 이유로 GPU에서 워핑해야합니다. 가장 좋은 방법은 무엇입니까? 버텍스 쉐이더에서 텍스처 좌표를 얻기 위해 곱 해보고 쿼드를 렌더링하려했지만 이상한 왜곡이 발생합니다. 보간이 예상대로 작동하지 않는지 확실하지 않습니다. 비교 출력을 첨부합니다 (두 가지가 다르지만 충분히 근접합니다).OpenGL ES 쉐이더에서 3x3 호모 그래피 행렬을 사용하는 방법은 무엇입니까?

GPU의 휘어짐 및 다른 이미지

절대 차 : OpenCV의 워프 다른 이미지

enter image description here

합성 :

enter image description here

EDIT : 다음

내 쉐이더입니다. 작업은 이미지입니다. ctification (에필린이 주사선이 됨) + 절대 차.

// Vertex Shader 

static const char* warpVS = STRINGIFY 
(
uniform highp mat3 homography1; 
uniform highp mat3 homography2; 
uniform highp int width; 
uniform highp int height; 
attribute highp vec2 position; 
varying highp vec2 refTexCoords; 
varying highp vec2 curTexCoords; 

highp vec2 convertToTexture(highp vec3 pixelCoords) { 
    pixelCoords /= pixelCoords.z; // need to project 
    pixelCoords /= vec3(float(width), float(height), 1.0); 
    pixelCoords.y = 1.0 - pixelCoords.y; // origin is in bottom left corner for textures 
    return pixelCoords.xy; 
} 

void main(void) 
{ 
    gl_Position = vec4(position/vec2(float(width)/2.0, float(height)/2.0) - vec2(1.0), 0.0, 1.0); 
    gl_Position.y = -gl_Position.y; 
    highp vec3 initialCoords = vec3(position, 1.0); 
    refTexCoords = convertToTexture(homography1 * initialCoords); 
    curTexCoords = convertToTexture(homography2 * initialCoords); 
} 

); 

// Fragment Shader 

static const char* warpFS = STRINGIFY 
(
varying highp vec2 refTexCoords; 
varying highp vec2 curTexCoords; 
uniform mediump sampler2D refTex; 
uniform mediump sampler2D curTex; 
uniform mediump sampler2D maskTex; 

void main(void) 
{ 
    if (texture2D(maskTex, refTexCoords).r == 0.0) { 
    discard; 
    } 

    if (any(bvec4(curTexCoords[0] < 0.0, curTexCoords[1] < 0.0, curTexCoords[0] > 1.0, curTexCoords[1] > 1.0))) { 
    discard; 
    } 

    mediump vec4 referenceColor = texture2D(refTex, refTexCoords); 
    mediump vec4 currentColor = texture2D(curTex, curTexCoords); 

    gl_FragColor = vec4(abs(referenceColor.r - currentColor.r), 1.0, 0.0, 1.0); 
} 

); 
+0

당신이 무엇을 설명 할 수 당신이하고있는 exclty, OpenGL은 현명한는, "나는 텍스처 좌표를 얻을 다음 쿼드를 렌더링하기 위해 버텍스 쉐이더에서 곱 시도하는 것은"입니다 조금은 모호하다. 버텍스와 텍스쳐가 정확히 무엇을 했습니까? 달성하고자하는 효과는 OpenGL을 사용하여 얻을 수 있으며 가능한 여러 가지 접근 방식이 있습니다. 이 그림만으로도 정확히 무엇이 잘못되었는지 판단하기가 어렵습니다. 아마도 당신은 비 - 아핀 투영 변환 권한으로 올바른 텍스처 변환을 얻지 못했을 것입니다. – derhass

+0

@derhass 달성하고자하는 쉐이더 코드와 작업을 추가했습니다. – aledalgrande

+0

@aledalgrande 안녕하세요! OpenGL에서 앱의 warpPerspective 부분을 수행 할 수 있었습니까? 코드가 공개되어 있습니까? 그렇지 않다면, 그것에 대해 갈 방법에 대한 정확한 조언을 해줄 수 있습니까? 비슷한 문제가 있습니다. warpPerspective는 감지 된 객체 대신 현재의 카메라 미리보기 프레임에 작은 비디오 프레임을 오버레이 할 때 여러 전화에서 약 200ms 가량 소요됩니다. 기본 AR. –

답변

2

픽셀 당 투영을해야한다고 생각합니다. refTexCoords 및 curTexCoords를 적어도 vec3으로 만든 다음 텍스처 룩업 전에 픽셀 쉐이더에서/z를 수행합니다. textureProj GLSL 명령을 더 잘 사용하십시오.

버텍스 쉐이더에서 선형적인 모든 작업을하고 싶지만 픽셀 당 프래그먼트 쉐이더에서 프로젝션과 같은 작업을 수행해야합니다.

몇 가지 배경에 도움이 될이 링크 : http://www.reedbeta.com/blog/2012/05/26/quadrilateral-interpolation-part-1/

+0

그러나 좌표가 'homography2 * initialCoords' 곱셈 후에 0,0 -> 640,480 범위에 있으면'texture2Dproj'를 어떻게 사용할 수 있습니까? – aledalgrande

+0

3x3 행렬로 (u, v, q) 좌표를 변환하여 3 요소 벡터 (u ', v', q ')를 얻습니다. q는 투영에 사용하는 것입니다. 3x3 행렬은 계산 q를 포함해야합니다. q의 어떤 값이 의미가 있는지 링크 된 기사를 참조하십시오. – starmole

+0

코드 예제를 제공해 주시겠습니까? – aledalgrande

관련 문제