본문 바로가기
C#

EmguImage 안에 IInputArray를 반환하는 getter

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

좋아요! EmguImage 안에 IInputArray를 반환하는 getter들을 아래처럼 추가하면 됩니다.

  • 전체 이미지 차용 참조(Dispose 금지)
  • ROI 기반 소유 참조(Dispose 필요)
  • (호환용) 예전 코드에서 쓰던 Image 프로퍼티도 함께 제공합니다.
// EmguImage 클래스 내부에 추가하세요 (namespace/using 동일)

/// <summary>
/// (호환용) 현재 내부 Mat을 IInputArray로 노출합니다. 
/// - 차용 참조(borrowed)이며, 호출자가 Dispose 하면 안 됩니다.
/// - 내부 m_Mat의 수명에 종속됩니다.
/// </summary>
public IInputArray Image
{
    get
    {
        EnsureNotDisposed();
        return IsVoid ? null : (IInputArray)m_Mat;
    }
}

/// <summary>
/// 현재 내부 Mat을 IInputArray로 반환합니다(차용 참조).
/// - Dispose 금지, 내부 m_Mat 수명에 종속.
/// - CvInvoke API에 바로 전달할 때 편리합니다.
/// </summary>
public IInputArray GetIInputArray()
{
    EnsureNotDisposed();
    return IsVoid ? null : (IInputArray)m_Mat;
}

/// <summary>
— /// 지정된 ROI 영역의 IInputArray를 생성하여 반환합니다(소유 참조).
/// - 내부적으로 새로운 Mat(View 또는 Clone)을 생성하므로
///   호출자가 반드시 Dispose 해야 합니다(예: using (var roi = CreateIInputArrayROI(...)) { ... }).
/// - clone=false: SubMat(View) 생성(빠름, 원본 버퍼 참조)
/// - clone=true : 실제 데이터 복제(원본 독립)
/// </summary>
/// <param name="roi">이미지 좌표계의 ROI</param>
/// <param name="clone">true면 복제, false면 View(SubMat)</param>
/// <returns>Mat (IInputArray로 사용 가능, 호출자 Dispose 필요)</returns>
/// <exception cref="InvalidOperationException">이미지가 비어 있을 때</exception>
/// <exception cref="ArgumentOutOfRangeException">ROI가 유효 영역과 겹치지 않을 때</exception>
public Mat CreateIInputArrayROI(Rectangle roi, bool clone = false)
{
    EnsureNotDisposed();
    if (IsVoid) throw new InvalidOperationException("Image is empty.");

    // 이미지 경계와 교집합으로 정규화
    var imgRect = new Rectangle(0, 0, Width, Height);
    var rc = Rectangle.Intersect(imgRect, roi);
    if (rc.Width <= 0 || rc.Height <= 0)
        throw new ArgumentOutOfRangeException(nameof(roi), "ROI is outside of the image.");

    // View 또는 Clone 생성 (둘 다 Mat이며 IInputArray로 사용 가능)
    var view = new Mat(m_Mat, rc);
    if (clone)
    {
        var own = view.Clone(); // 독립 버퍼
        view.Dispose();
        return own;             // 호출자 Dispose 필요
    }
    return view;                 // 호출자 Dispose 필요 (원본 버퍼 뷰)
}

사용 예시

// 1) 차용 참조: Dispose 금지
CvInvoke.CvtColor(emguImage.GetIInputArray(), dstMat, ColorConversion.Bgr2Gray);

// 2) ROI 소유 참조: 반드시 Dispose
var roiRect = new Rectangle(100, 100, 200, 150);
using (Mat roi = emguImage.CreateIInputArrayROI(roiRect, clone: false))
{
    CvInvoke.GaussianBlur(roi, roi, new Size(5,5), 0);
}

// 3) (호환) 예전처럼 m_SrcImage.Image 접근
CvInvoke.Canny((IInputArray)emguImage.Image, edgesMat, 50, 150);

왜 이렇게 나눴나요?

  • Borrowed(차용): 내부 m_Mat을 그대로 노출 → Dispose 금지(내부 수명에 종속). CvInvoke 호출만 하고 끝낼 때 적합.
  • Owned(소유): ROI나 복제가 필요한 경우 새 Mat을 만들어 전달 → 반드시 Dispose 필요. 후처리/보관 등 수명 독립이 필요할 때 적합.

필요하면 IOutputArray 버전도 같은 패턴으로 만들어 드릴게요.

반응형