본문 바로가기
programming | development/unity

Unity + OpenCVSharp2 -IplImage를 Texture2D로 변환

by foooo828 2022. 1. 29.
반응형

1. byte[] 쓰기

byte[] GetRawTextureData()  ,  LoadRawTextureData(byte[] data)

public Texture2D srctexture;
public Texture2D dstImage;
public Material mat;
private IplImage src;
private CvSize size;
private OpenCVMethod Convert;
void ConvertImage()
{
byte[] bytes = srctexture.GetRawTextureData();
size = new CvSize(srctexture.width, srctexture.height);
src = IplImage.FromPixelData(size, BitDepth.U8, 4, pixel32);
byte[] pixel32byte = Convert.FlipImageByte(src);
dstImage.filterMode = FilterMode.Point;
dstImage = new Texture2D(size.Width, size.Width, TextureFormat.RGBA32, false);
dstImage.Apply();
mat.mainTexture = dstImage;
}

 

private IplImage flip;
public byte[] FlipImageByte(IplImage src)
{
flip = new IplImage(src.Size, BitDepth.U8, 4);
Cv.Flip(src, flip, FlipMode.Y);
int length = flip.Height * flip.Width * 4;
byte[] data = new byte[length];
Marshal.Copy(flip.ImageData, data, 0, length);
return data;
}

 

dstImage.SetPixelData(dstpixel32byte,0,0);

LoadRawTextureData   대신 SetPixelData 함수도 사용 가능하지만 get, set pixel 류 함수는 구식이며 RGBA32, RGB24 또는 Alpha8 텍스처 형식에서만 작동하기 때문에 (사용시 암묵적으로 텍스처를 RGBA32 로 변환)

GetRawTextureDataLoadRawTextureData 를 사용하는것을 더 추천한다고함

 

UnityException: LoadRawTextureData: not enough data provided (will result in overread).

LoadRawPixelData 사용시 이런 에러가 뜰 수 있는데 소스와 결과 텍스처의 포멧을 일치시켜주면 해결된다.

 

2. IntPtr 쓰기 

LoadRawTextureData(IntPtr data, int size)

void ConvertImage()
{
Color32[] pixel32 = srctexture.GetPixels32();
size = new CvSize(srctexture.width, srctexture.height);
src = IplImage.FromPixelData(size, BitDepth.U8, 4, pixel32);
IplImage dst = Convert.FlipImage(src);
dstImage = new Texture2D(size.Width, size.Height, TextureFormat.RGBA32, false);
dstImage.LoadRawTextureData(dst.ImageData, size.Width * size.Height * 4);
dstImage.Apply();
mat.mainTexture = dstImage;
}

 

public IplImage FlipImage(IplImage src)
{
flip = new IplImage(src.Size, BitDepth.U8, 4);
Cv.Flip(src, flip, FlipMode.Y);
return flip;
}

 

3. Color32[] 쓰기

Color32[] GetPixels32()  ,  SetPixels32(Color32[] colors)

void ConvertImage()
{
Color32[] pixel32 = srctexture.GetPixels32();
size = new CvSize(srctexture.width, srctexture.height);
src = IplImage.FromPixelData(size, BitDepth.U8, 4, pixel32);
Color32[] resultColor32 = Convert.FlipImage(src);
dstImage = new Texture2D(srctexture.width, srctexture.height, TextureFormat.RGBA32, false);
dstImage.SetPixels32(resultColor32);
dstImage.Apply();
mat.mainTexture = dstImage;
}

 

public Color32[] FlipImage(IplImage src)
{
flip = new IplImage(src.Size, BitDepth.U8, 4);
Cv.Flip(src, flip, FlipMode.Y);
int length = flip.Height * flip.Width * 4;
byte[] data = new byte[length];
Marshal.Copy(flip.ImageData, data, 0, length);
return ByteToColor32(data, 4);
}

 

byte[] -> Color32[] 변환 해줘야함

public static Color32[] ByteToColor32(byte[] byteData, int chanel)
{
Color32[] cvtpixel32 = new Color32[byteData.Length / chanel];
int idx = 0;
if (chanel == 4)
{
for (int i = 0; i < cvtpixel32.Length; i++ , idx += 4)
{
cvtpixel32[i].r = byteData[idx];
cvtpixel32[i].g = byteData[idx + 1];
cvtpixel32[i].b = byteData[idx + 2];
cvtpixel32[i].a = byteData[idx + 3];
}
}
else if (chanel == 1)
{
for (int i = 0; i < cvtpixel32.Length; i++)
{
cvtpixel32[i].r = cvtpixel32[i].g = cvtpixel32[i].b = byteData[i];
}
}
return cvtpixel32;
}

 

 

반응형

'programming | development > unity' 카테고리의 다른 글

Strip Particle System  (0) 2022.02.23
Unity + OpenCVSharp2 - WebcamTexture  (0) 2022.01.30
Unity에서 Firebase쓰기  (0) 2022.01.06
Unity + Realsense  (0) 2021.11.17
Bezier Curve 이용해서 VR 텔레포트 ray 만들기  (0) 2021.11.01

댓글