카메라 코드를 만지다 보면 YUV 데이터를 crop, flip, rotate 해야할 일이 가끔 생긴다.
허나 이 예제코드는 구글링을 아무리 해도 안나온다.
답답해서 필자가 직접 만들어서 전 세계 사람들에게 공유한다.
이글을 보는 영상처리 전공님들 양심있으면 본인들이 하는 코드 세계평화를 위해 공유좀 해주세요.
구글링해서 하나도 안나오는게 말이나 됩니까. YUV가 나온지 몇십년인데!
작동원리는 다음과 같다
1. input Y좌표와 매칭되는 output Y좌표를 구한다.
2. Y좌표와 매칭되는 UV좌표를 구한다.
3. Y영역을 이중포문으로 한번 긁는다.
코드 내용에 잘못된 표기나 에러가 있을 수 있다. 예를들어 u를 v로 잘못 적는다던지.
나도 yuv 잘몰라요
스택오버플로우에 떠도는 코드 참고하였음
When developing camera code, Sometimes we need to do YUV data crop, flip and rotate.
But no matter how many times I try to google to find example code, there is no fucking sample code.
So I made it myself and share it with people all around the world.
The principle is as follows
1. Find the output Y coordinates that match the input Y coordinates.
2. Find the UV coordinates that match the Y coordinates.
3. Scratch the Y area once with nested for loop
image processing majors who are seeing this, if you have any conscience, share fucking your code for world peace
How can i google it and not even fucking come out a thing? It's been decades since YUV came out.
There may be a mistake or error in the code. For example, writing "u" incorrectly as "v"
YUV Crop, java code
private byte[] cropNV21(byte[] out, byte[] yuv420sp, int inputW, int inputH, int startX, int startY, int cropWidth, int cropHeight) {
for(int y = startY; y < startY + cropHeight; y++){
for(int x = startX ; x< startX + cropWidth; x++){
int outputX = x - startX;
int outputY = y - startY;
out[outputY * cropWidth + outputX] = yuv420sp[inputW * y + x];
int u = (inputW * inputH) + (inputW) * (y >> 1) + 2*(x>>1);
int v = u+1;
out[cropWidth*cropHeight + (cropWidth) * (outputY >> 1) + 2*(outputX>>1)] = yuv420sp[u];
out[cropWidth*cropHeight + (cropWidth) * (outputY >> 1) + 2*(outputX>>1)+1] = yuv420sp[v];
}
}
return out;
}
용어설명, terminology
xi : x input
xo : x output
fs : Y area
qs : uv area
wi : width input
wo : width output
hi : height input
ho : height output
YUV flip, c++ code
void flipNV21(unsigned char* input, unsigned char* output, int width, int height,int flip) {
int x,y,xi,yi,wi,hi;
int wo=width, ho=height;
for ( x = 0; x < wo; x++) {
for (y = 0; y < ho; y++) {
xi = x;
yi = y;
wi=wo;
hi=ho;
if(flip){
xi = wi - xi - 1;
}
else{
yi = hi - yi - 1;
}
output[wo * y + x] = input[wi * yi + xi];
int fs = wo * ho;
int qs = (fs >> 2);
xi = (xi >> 1);
yi = (yi >> 1);
int vx = (x >> 1);
int vy = (y >> 1);
int vwi = (wi >> 1);
int vhi = (hi >> 1);
int vwo = (wo >> 1);
int vho = (ho >> 1);
int vi = fs + (vwi * yi + xi) * 2;
int vo = fs + (vwo * vy + vx) * 2;
int ui = vi + 1;
int uo = vo + 1;
output[vo] = input[vi];
output[uo] = input[ui];
}
}
}
YUV rotate, c++ code
void rotateNV21(unsigned char* input, unsigned char* output, int width, int height, int rotation) {
int swap = (rotation == 90 || rotation == 270);
int yflip = (rotation == 90 || rotation == 180);
int xflip = (rotation == 270 || rotation == 180);
int x,y,xi,yi,wi,hi;
int wo=width, ho=height;
if(swap){
wo=height;
ho=width;
}
for ( x = 0; x < wo; x++) {
for (y = 0; y < ho; y++) {
xi = x;
yi = y;
wi=wo;
hi=ho;
if (swap) {
xi = y;
yi = x;
wi=ho;
hi=wo;
}
if (yflip) {
yi = hi - yi - 1;
}
if (xflip) {
xi = wi - xi - 1;
}
output[wo * y + x] = input[wi * yi + xi];
int fs = wo * ho;
int qs = (fs >> 2);
xi = (xi >> 1);
yi = (yi >> 1);
int vx = (x >> 1);
int vy = (y >> 1);
int vwi = (wi >> 1);
int vhi = (hi >> 1);
int vwo = (wo >> 1);
int vho = (ho >> 1);
int vi = fs + (vwi * yi + xi) * 2;
int vo = fs + (vwo * vy + vx) * 2;
int ui = vi + 1;
int uo = vo + 1;
output[vo] = input[vi];
output[uo] = input[ui];
}
}
}
'영상처리' 카테고리의 다른 글
HRV 신호 SDNN RMSSD의 차이 (0) | 2024.05.22 |
---|---|
DSP 옛날기억 끄적끄적 (0) | 2024.05.17 |
DC 성분이란 (DC Component) (0) | 2024.05.14 |
RGBA to NV21 (0) | 2023.06.02 |
YV12toNV21, YV12toNV12, NV12toYV12, NV21toYV12, NV12toNV21, NV21toNV12 (0) | 2022.06.08 |
댓글