원시 YUV 파일을 NV12 형식으로 표시하는 데 문제가 있습니다.OpenGl에서 YUV 디스플레이에 대한 도움이 필요합니다.
내가 선택한 프레임을 표시 할 수 있지만, 여전히 주로 핑크와 녹색의 특정 음영이있는 흑백으로되어 있습니다. 여기
내 출력이 어쨌든 alt text http://i32.tinypic.com/hv0vih.png
과 같은 방법 여기, 내 프로그램이 작동하는 방법이다. (이것은 코코아/objective-c에서 행해지지만, 문법이 아닌 프로그램 알고리즘에 대한 전문가의 조언이 필요합니다.)
프로그램 실행에 앞서 YUV 파일은 "test.yuv"라는 이진 파일에 저장됩니다. . 파일은 NV12 형식으로되어 있습니다. 즉, Y 계획이 먼저 저장되고 UV 계획이 인터레이스됩니다. 필자가 테스트를 많이했기 때문에 파일 추출에 문제가 없습니다.
가 시작하는 동안, 나는 Y는, U는, V 플로트이는 Y 평면
값 존중에 진/8 바이트/바이트/문자로 변환하는 룩업 테이블을 생성하는 것은 내 코드입니다
-(void)createLookupTableY //creates a lookup table for converting a single byte into a float between 0 and 1
{
NSLog(@"YUVFrame: createLookupTableY");
lookupTableY = new float [256];
for (int i = 0; i < 256; i++)
{
lookupTableY[i] = (float) i /255;
//NSLog(@"lookupTableY[%d]: %f",i,lookupTableY[i]);//prints out the value of each float
}
}
U 플레인 룩업 테이블
-(void)createLookupTableU //creates a lookup table for converting a single byte into a float between 0 and 1
{
NSLog(@"YUVFrame: createLookupTableU");
lookupTableU = new float [256];
for (int i = 0; i < 256; i++)
{
lookupTableU[i] = -0.436 + (float) i/255* (0.436*2);
NSLog(@"lookupTableU[%d]: %f",i,lookupTableU[i]);//prints out the value of each float
}
}
그리고 V 룩업 테이블
는 "I가 YUV 데이터로 변환하려고하고 불리는 RGB 버퍼 배열로 저장이 시점 이후, I는 Y & UV 계획을 추출하고이 시점에서, 두 개의 버퍼에 yBuffer & uvBuffer
를 저장할 frameImage는 "
-(void)sortAndConvert//sort the extracted frame data into an array of float
{
NSLog(@"YUVFrame: sortAndConvert");
int frameImageCounter = 0;
int pixelCounter = 0;
for (int y = 0; y < YUV_HEIGHT; y++)//traverse through the frame's height
{
for (int x = 0; x < YUV_WIDTH; x++)//traverse through the frame's width
{
float Y = lookupTableY [yBuffer [y*YUV_WIDTH + x] ];
float U = lookupTableU [uvBuffer [ ((y/2) * (YUV_WIDTH/2) + (x/2)) * 2 ] ];
float V = lookupTableV [uvBuffer [ ((y/2) * (YUV_WIDTH/2) + (x/2)) * 2 + 1] ];
float RFormula = Y + 1.13983f * V;
float GFormula = Y - 0.39465f * U - 0.58060f * V;
float BFormula = Y + 2.03211f * U;
frameImage [frameImageCounter++] = [self clampValue:RFormula];
frameImage [frameImageCounter++] = [self clampValue:GFormula];
frameImage [frameImageCounter++] = [self clampValue:BFormula];
}
}
}
는 그래서 기본적으로
-(void)drawFrame:(int)x
{
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, YUV_WIDTH, YUV_HEIGHT, 0, GL_RGB, GL_FLOAT, frameImage);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0);
glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0);
glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);
glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0);
glEnd();
glFlush();
}
A의이 내 프로그램 OpenGL을
의 이미지를 그리는 시도 너트 쉘. 본질적으로 이진 YUV 파일을 읽고 모든 데이터를 char 배열 버퍼에 저장합니다. 그런 다음이 값을 존중받는 YUV 부동 소수점 값으로 변환합니다.여기 내가 생각하는 오류는 다음과 같습니다. Y 룩업 테이블에서 나는 Y 평면을 [0,1]로 표준화하고 U 평면에서는 [-0.435,0.436] 사이의 값을 표준화했으며 V 비행기 I는 그것을 표준화했다 [-0.615,0.615]. 위키피디아에 따르면 YUV 값 범위이기 때문에이 작업을 수행했습니다.
그리고 YUV에서 RGB 공식은 위키피디아의 공식과 같습니다. 나는 또한 다양한 다른 수식을 시도했으며 이것은 프레임의 거친 전망을 제공하는 유일한 수식입니다. 누구나 내 프로그램이 YUV 프레임 데이터를 올바르게 표시하지 않는 이유를 추측 할 수 있습니다. 내 표준화 기술과 관련이 있다고 생각하지만 괜찮아 보인다.
많은 테스트를 해본 결과 오류를 조회하는 테이블이 100 % 확실하다는 것을 확신합니다. 나는 나의 설정 공식이 옳다고 생각하지 않는다.
읽고있는 사람에게 보내는 메모입니다. 입니다.가장 긴 시간 동안 프레임 데이터를 올바르게 추출 할 수 없기 때문에 프레임이 올바르게 표시되지 않았습니다. . 프레임 데이터를 올바르게 추출 할 수 없었습니다. 처음 프로그램을 시작할 때
, 제가 의 클립의 30 프레임 먼저 데이터 파일에 기입 된 모든 30 Y 평면 datas 말하는 것으로 인상 이었다 는 UV 평면 datas하여 다음 하였다.I 재판 통해 발견 오류가 YUV 데이터 파일, 구체적 NV12는, 상기 데이터 파일은 다음 방식으로 저장 것이 무엇 이었는가
Y (1) UV (1) Y (2) UV (2) ... ... 난 당신이
을 제안 무엇에 내 코드를 변경float U = lookupTableU [uvBuffer [ (y * (YUV_WIDTH/4) + (x/4)) * 2 ] ] float V = lookupTableU [uvBuffer [ (y * (YUV_WIDTH/4) + (x/4)) * 2 + 1] ]
@nschmidt
는이 내가 여기 alt text http://i26.tinypic.com/kdtilg.png
콘솔에서 인쇄 라인 얻을 결과입니다. 난 번역 및 frameImage 어레이에 저장되는 Y, U, V 및 RGB 값에 대한 값을 출력이다
YUV : 0.658824, -0.022227, -0.045824] RGBFinal [0.606593,0.694201,0.613655 ]
YUV : 0.643137, -0.022227, -0.045824] RGBFinal [0.590906,0.678514,0.597969]
YUV : 0.607843, -0.022227, -0.045824] RGBFinal [0.555612,0.643220,0.562675]
YUV : [0.592157, -0.022227, -0.045824] RGB 최종 : [0.539926,0.627534,0.546988]
YUV [0.643137,0.025647,0.151941] RGBFinal [0.816324,0.544799,0.695255]
YUV [0.662745,0.025647,0.151941] RGBFinal [0.835932,0.564406,0.714863]
YUV : 0.690196 , 0.025647,0.151941] RGBFinal : [0.863383,0.591857,0.742314]
업데이트 문제는 결국 nschmidt에서 추천 덕분에 해결되었다 2009
7 월 13 일. 내 YUV 파일은 실제로 YUV 4 : 1 : 1 형식이었습니다. 원래 YUV NV12 형식이라고 들었습니다. 어쨌든, 나는 결과를 당신과 공유하고 싶습니다. 여기
출력
alt text http://i32.tinypic.com/35b9xf8.png
이고
float Y = (float) yBuffer [y*YUV_WIDTH + x] ;
float U = (float) uvBuffer [ ((y/2) * (YUV_WIDTH/2) + (x/2)) ] ;
float V = (float) uvBuffer [ ((y/2) * (YUV_WIDTH/2) + (x/2)) + UOffset] ;
float RFormula = (1.164*(Y-16) + (1.596* (V - 128)));
float GFormula = ((1.164 * (Y - 16)) - (0.813 * ((V) - 128)) - (0.391 * ((U) - 128)));
float BFormula = ((1.164 * (Y - 16)) + (2.018 * ((U) - 128)));
frameImage [frameImageCounter] = (unsigned char)((int)[self clampValue:RFormula]);
frameImageCounter ++;
frameImage [frameImageCounter] = (unsigned char)((int)[self clampValue:GFormula]);
frameImageCounter++;
frameImage [frameImageCounter] = (unsigned char)((int) [self clampValue:BFormula]);
frameImageCounter++;
GLuint texture;
glGenTextures(1, &texture);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, YUV_WIDTH, YUV_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, frameImage);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE_SGIS);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE_SGIS);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0);
glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0);
glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);
glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0);
glEnd();
NSLog(@"YUVFrameView: drawRect complete");
glFlush();
본질적, I 원시 파일 추출을 NSData 사용 다음 디코드 내 코드이다. char 배열 버퍼에 저장된다. YUV에서 RGB 로의 변환의 경우 위의 공식을 사용하여 값을 [0 : 255]로 고정했습니다. 그런 다음 OpenGL에서 2DTexture를 사용하여 표시했습니다.
미래에 YUV를 RGB로 변환하는 경우 위 공식을 사용하십시오. 이전 게시물에서 YUV - RGB 변환 공식을 사용하는 경우 RGB 값이 [0 : 1] 사이에 고정되어있는 값에서 GL_Float의 텍스처를 표시해야합니다.
인 것처럼 보이도록 이미지를 추가했습니다. 조정으로 내 프로그램을 테스트 한 결과 마침내 효과가있었습니다. 고마워요. 당신이 옳았다는 것이 드러났습니다. U & V 비행기는 원래 내가 말했던 것처럼 비월 주사가 아닙니다. 정말 감사드립니다. 나는 – ReachConnection
아무런 문제가 없다고 평가하고 있습니다 :). 레코드의 경우 4 : 1 : 1 인 형식에 대한 첫 번째 추측은 실제로 올바르지 않습니다. 당신은 4 : 2 : 2 형식입니다. 실제 문제는 데이터가 인터리브되지 않는 것뿐이었습니다. – nschmidt
@ReachConnection : [self clampValue : RFormula]가 무엇을하고 있는지 말해 줄 수 있습니까? 당신의 코드를 사용하여 YUV422에서 UIImage를 얻을 계획입니다. –