본문 바로가기
카테고리 없음

EmguCV 이미지 깊은 복사(Deep Copy) vs 얕은 복사(Shallow Copy)

by 공부봇 2025. 9. 8.
반응형

1) 깊은 복사(Deep Copy) vs 얕은 복사(Shallow Copy)

얕은 복사 (clone == false)

  • 뜻: 픽셀 데이터를 새로 복제하지 않고 같은 픽셀 버퍼를 공유합니다. 보통은 헤더/메타데이터(크기, 타입, 포인터)만 “복사”하고 실제 바이트 배열은 공유해요.
  • 장점: 거의 즉시 끝나고 메모리 추가 사용이 없음(아주 빠름).
  • 주의점:
    • 원본/사본이 서로 영향을 줍니다. 한쪽에서 픽셀을 바꾸면 다른 쪽에도 그대로 반영돼요.
    • 수명(Dispose) 얽힘: 같은 버퍼를 공유하므로 원본이 해제되면 사본도 무효가 될 수 있습니다.
      특히 지금 코드처럼 clone == false에서 내부에 같은 Mat 인스턴스를 보관하면, 호출자가 source.Dispose() 해버리면 내부도 같이 무효가 됩니다.
      → 얕은 복사를 쓸 땐 “이제부터 이 Mat의 소유권은 내가 가진다(호출자는 더 이상 Dispose/수정하지 않는다)” 같은 명확한 계약이 필요합니다.

예시:

var src = CvInvoke.Imread("lenna.png", ImreadModes.Color);

// 얕은 복사: 같은 픽셀 버퍼 공유(여기서는 심지어 같은 Mat 인스턴스를 가리킬 수도 있음)
var shallow = src; // 또는 헤더만 다른 shallow Mat이라도 버퍼는 공유됨

// shallow에 그리면 src도 같이 바뀜
CvInvoke.Rectangle(shallow, new Rectangle(10,10,50,50), new MCvScalar(0,0,255), 2);

// src를 해제하면 shallow도 사실상 무효(공유 버퍼 소멸 가능)
src.Dispose();

참고: ROI(new Mat(src, roiRect))도 얕은 복사(공유)입니다. ROI에 쓴 픽셀은 원본에도 반영됩니다.

깊은 복사 (clone == true)

  • 뜻: 픽셀 버퍼 자체를 완전히 새로 할당하고, 원본의 픽셀 값을 복제합니다.
  • 장점: 한쪽을 수정/해제해도 다른 쪽은 영향 없음(완전 독립).
  • 단점: 픽셀 메모리만큼 복사 비용/메모리 사용 증가가 발생합니다. 큰 이미지일수록 비용이 큼.

예시:

var src = CvInvoke.Imread("lenna.png", ImreadModes.Color);

// 깊은 복사: 픽셀을 통째로 복제
var deep = src.Clone();

// deep을 수정해도 src는 그대로
CvInvoke.GaussianBlur(deep, deep, new Size(9,9), 0);

// src를 해제해도 deep은 여전히 유효
src.Dispose();

언제 무엇을 쓰나?

  • 읽기 전용으로 잠깐 전달하거나, 즉시 처리 후 버린다면 얕은 복사로 성능을 챙길 수 있습니다.
  • 오래 보관하거나, 독립적으로 수정/해제해야 하거나, 다른 스레드/모듈로 넘긴다면 깊은 복사가 안전합니다.
  • 현재 SetImage(Mat source, bool clone = true)는 기본이 깊은 복사라서 “안전”을 기본값으로 택했습니다. clone == false를 쓸 때는 “이제부터 이 source는 EmguImage가 소유한다”는 소유권 계약을 지키는 게 안전합니다.

핵심 요약

  • 얕은 복사: 픽셀 버퍼를 공유 → 빠름/메모리 절약, 대신 수정/수명 얽힘 주의.
  • 깊은 복사: 픽셀을 통째로 복제 → 안전/독립하지만 메모리/시간 비용 증가.
반응형