반응형
좋아요! 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 버전도 같은 패턴으로 만들어 드릴게요.
반응형
'C#' 카테고리의 다른 글
sealed를 왜 써야 할까? (0) | 2025.09.19 |
---|---|
C#의 readonly 키워드 (0) | 2025.09.19 |
null-coalescing assignment 연산자(??=) 가 C# 8.0에서 추가된 문법이라, C# 7.3 컴파일러로는 사용할 수 없다는 뜻입니다. (0) | 2025.09.11 |
VisionThread/EmguVision 라이브·검사 공통 파이프라인 리팩토링 (풀코드) (0) | 2025.09.10 |
private static bool IsFiniteFloat(float v) => !(float.IsNaN(v) || float.IsInfinity(v)); (0) | 2025.09.09 |
소멸자(~EmguVision)로 GDI 리소스(Pen)를 해제하는 방식은 권장되지 않습니다. (0) | 2025.09.09 |
ScrollableControl을 상속받았다는 건, “이 컨트롤은 화면(뷰포트)보다 큰 가상의 캔버스를 갖고, 자동 스크롤바/스크롤 오프셋 관리까지 운영체제가 대신 해주는 컨테이너”라는 뜻입니다. (0) | 2025.09.09 |
C# APM(Asynchronous Programming Model) 패턴 (1) | 2025.01.20 |