본문 바로가기
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

댓글