영상 처리 (6) 그 레이스 케 일 형태학 의 부식 과 팽창

그 레이스 케 일 이미지 의 부식 연산 에 대한 수학 적 정 의 는:
그 중에서 g (x, y) 는 부식 후의 그 레이스 케 일 이미지 이 고 f (x, y) 는 원 그 레이스 케 일 이미지 이 며 B 는 구조 요소 이다.
자연 언어 로 설명 하면:
          부식 연산 은 구조 요소 가 확 정 된 이웃 블록 에서 이미지 값 과 구조 요소 값 의 차 이 를 선택 하 는 최소 값 이다.
그 레이스 케 일 이미지 의 팽창 연산 의 수학 적 정 의 는:
자연 언어 로 설명 하면:
          팽창 연산 은 구조 요소 에 의 해 확 정 된 인접 블록 에서 이미지 값 과 구조 요소 값 의 합 을 선택 하 는 최대 값 이다.
그 레이스 케 일 형태학 에 서 는 일반적으로 평탄 한 구조 요 소 를 선택한다.이른바 '평탄' 이란 구조 원소 의 높이 가 0 이라는 것 을 말한다.따라서 이러한 구조 요소, B 의 값 은 D 에 있 습 니 다.­b ­­정의 필드 안의 모든 좌 표 는 0 이 고 위의 두 공식 은 다시 쓸 수 있 습 니 다.
나 는 이 RGB 세 채널 을 모두 처리 하여 그 레이스 케 일 팽창 과 부식 연산 을 컬러 이미지 에 도 효과 적 으로 만 들 었 다.그러나 현재 컬러 이미지 의 부식 과 팽창 에 대해 서 는 통 일 된 정의 가 없 으 며 이 방법 은 참고 만 한다.
다음은 알고리즘 구현 (선택 한 템 플 릿 은 3 * 3):
  /// 
    ///     
    /// 
    ///     
    ///     
    ///      true    false
    public static bool Erode(Bitmap srcBmp, out Bitmap dstBmp) {
        if (srcBmp == null) {
            dstBmp = null;
            return false;
        }
        Bitmap grayBmp = null;
        dstBmp = new Bitmap(srcBmp);
        BitmapData bmpDataGray = null;
        ToGray(srcBmp, out grayBmp);
        bmpDataGray = grayBmp.LockBits(new Rectangle(0, 0, grayBmp.Width, grayBmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
        BitmapData bmpDataSrc = srcBmp.LockBits(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        BitmapData bmpDataDst = dstBmp.LockBits(new Rectangle(0, 0, dstBmp.Width, dstBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        unsafe {
            int[] grayValueArray = new int[25];
            long[] index = new long[25];
            for (int i = 0; i < 25; i++) {
                grayValueArray[i] = 255;
            }
            byte* ptrSrc = (byte*)bmpDataSrc.Scan0;
            byte* ptrDst = (byte*)bmpDataDst.Scan0;
            byte* ptrGray = null;           
            ptrGray = (byte*)bmpDataGray.Scan0;              
                    for (int i = 0; i < bmpDataSrc.Height; i++) {//    ,             
                        for (int j = 0; j < bmpDataSrc.Width; j++) {
                                grayValueArray[0] = ptrGray[Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3];
                                grayValueArray[1] = ptrGray[Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + j * 3];
                                grayValueArray[2] = ptrGray[Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3];
                                grayValueArray[3] = ptrGray[i * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3];
                                grayValueArray[4] = ptrGray[i * bmpDataSrc.Stride + j * 3];
                                grayValueArray[5] = ptrGray[i * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3];
                                grayValueArray[6] = ptrGray[(i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3];
                                grayValueArray[7] = ptrGray[(i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + j * 3];
                                grayValueArray[8] = ptrGray[(i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3];
                                index[0] = Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3;
                                index[1] = Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + j * 3;
                                index[2] = Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3;
                                index[3] = i * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3;
                                index[4] = i * bmpDataSrc.Stride + j * 3;
                                index[5] = i * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3;
                                index[6] = (i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3;
                                index[7] = (i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + j * 3;
                                index[8] = (i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3;
                                Array.Sort(grayValueArray, index);
                                ptrDst[i * bmpDataDst.Stride + j * 3] = ptrSrc[index[0]];
                                ptrDst[i * bmpDataDst.Stride + j * 3 + 1] = ptrSrc[index[0] + 1];
                                ptrDst[i * bmpDataDst.Stride + j * 3 + 2] = ptrSrc[index[0] + 2];
                        }
                    }
            srcBmp.UnlockBits(bmpDataSrc);
            dstBmp.UnlockBits(bmpDataDst);
        }
        return true;
    }
 /// 
    ///     
    /// 
    ///     
    ///     
    ///      true    false
    public static bool Erode(Bitmap srcBmp, out Bitmap dstBmp) {
        if (srcBmp == null) {
            dstBmp = null;
            return false;
        }
        Bitmap grayBmp = null;
        dstBmp = new Bitmap(srcBmp);
        BitmapData bmpDataGray = null;
		ToGray(srcBmp, out grayBmp);
        bmpDataGray = grayBmp.LockBits(new Rectangle(0, 0, grayBmp.Width, grayBmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
        BitmapData bmpDataSrc = srcBmp.LockBits(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        BitmapData bmpDataDst = dstBmp.LockBits(new Rectangle(0, 0, dstBmp.Width, dstBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        unsafe {
            int[] grayValueArray = new int[25];
            long[] index = new long[25];
            for (int i = 0; i < 25; i++) {
                grayValueArray[i] = 255;
            }
            byte* ptrSrc = (byte*)bmpDataSrc.Scan0;
            byte* ptrDst = (byte*)bmpDataDst.Scan0;
            byte* ptrGray = null;           
            ptrGray = (byte*)bmpDataGray.Scan0;              
                    for (int i = 0; i < bmpDataSrc.Height; i++) {
                        for (int j = 0; j < bmpDataSrc.Width; j++) {//    ,             
                                grayValueArray[0] = ptrGray[Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3];
                                grayValueArray[1] = ptrGray[Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + j * 3];
                                grayValueArray[2] = ptrGray[Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3];
                                grayValueArray[3] = ptrGray[i * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3];
                                grayValueArray[4] = ptrGray[i * bmpDataSrc.Stride + j * 3];
                                grayValueArray[5] = ptrGray[i * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3];
                                grayValueArray[6] = ptrGray[(i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3];
                                grayValueArray[7] = ptrGray[(i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + j * 3];
                                grayValueArray[8] = ptrGray[(i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3];
                                index[0] = Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3;
                                index[1] = Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + j * 3;
                                index[2] = Math.Abs(i - 1) % bmpDataSrc.Height * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3;
                                index[3] = i * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3;
                                index[4] = i * bmpDataSrc.Stride + j * 3;
                                index[5] = i * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3;
                                index[6] = (i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + Math.Abs(j - 1) % bmpDataSrc.Width * 3;
                                index[7] = (i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + j * 3;
                                index[8] = (i + 1) % bmpDataSrc.Height * bmpDataSrc.Stride + (j + 1) % bmpDataSrc.Width * 3;
                                Array.Sort(grayValueArray, index);
                                ptrDst[i * bmpDataDst.Stride + j * 3] = ptrSrc[index[8]];
                                ptrDst[i * bmpDataDst.Stride + j * 3 + 1] = ptrSrc[index[8] + 1];
                                ptrDst[i * bmpDataDst.Stride + j * 3 + 2] = ptrSrc[index[8] + 2];
                        }
                    }
            srcBmp.UnlockBits(bmpDataSrc);
            dstBmp.UnlockBits(bmpDataDst);
        }
        return true;
    }

효과 도

좋은 웹페이지 즐겨찾기