Canny

예갈조·2024년 12월 5일

Tumor Track Project

목록 보기
7/25

Edge 검출 방법


  • 사람: 이미지의 색이나 밝기가 급격하게 변하는 부분
  • 컴퓨터: 이미지 픽셀 값의 변화율이 큰 부분
    • 픽셀 값의 변화율: 미분으로 구함
    • 미분 값(a)이 특정 값(T)보다 크면 엣지로 판단 가능
  • 근데 픽셀은 행렬로 저장되어서 미분이 불가능하다.
    • 행렬은 이산함수로 취급을 하고 미분은 연속함수에서만 가능하다.
    • 그러므로 미분 근사화 방법을 사용하기
      • forward difference
      • backward difference
      • centered difference → 보통 자신을 제외한 앞, 뒤에 있는 픽셀 값을 이용하는 중앙 차분이 오류가 가장 작기 때문에 주로 사용
  • 미분 마스크 → 그래디언트(기울기 크기) 표현 → threshold보다 크면 edge로 판단



Canny Edge Detection


  • Canny() 함수 구성요소

    void Canny(Input Image, Output Image, double threshold1, double threshold2, iny apertureSize = 3, bool L2gradient = FALSE);
    • threshold1: 하단 임계값

      • edge 주변도 edge일 확률이 높다는 점을 이용하여 threshold2에 의해 판단된 edge와 인접한 부분을 edge로 판단할 때 사용하는 임계값
    • threshold2: 상단 임계값

      • 실질적으로 edge를 판단하는 임계값
      • 임계값이 커질수록 검출되는 edge가 적어짐
    • apertureSize: 사용되는 Sobel 미분 마스크의 커널 크기, 디폴트는 3

    • L2gradient
      - TRUE: L2 norm
      - FALSE: L1 norm

      → L2가 L1보다 더 정확하지만 속도가 느려서 L1을 기본값으로 사용함

      → threshold2를 너무 높게 설정하면 엣지가 잘 검출되지 않고, threshold1을 너무 낮게 설정하면 원치 않은 엣지까지 검출할 수 있음. 그래서 적절한 값을 잘 찾아야 함



내가 project에 사용한 코드와 실행 결과


  • 코드
    void CTreeCtrlDlg::OnClickedCheckEdge()
    {
    	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    	if (m_chEdge.GetCheck() == BST_CHECKED) {
    		if (!m_matImage.empty())
    		{
    			// m_matOriginalImage = m_matImage.clone();
    
    			Mat imgEdge;
    			Canny(m_matImage, imgEdge, 100, 150);
    
    			resize(imgEdge, imgEdge, Size(200, 200));
    
    			m_matImage = imgEdge;
    
    			CreateBitmapInfo(m_matImage.cols, m_matImage.rows, m_matImage.channels() * 8);
    
    			DrawImage();
    		}
    		else {
    			AfxMessageBox(_T("이미지를 선택하세요"));
    			m_chEdge.SetCheck(BST_UNCHECKED);
    		}
    	}
    	// 흑백 체크 해제 시 원본 이미지로 복원
    	else {
    		if (!m_matOriginalImage.empty()) {
    			m_matImage = m_matOriginalImage.clone(); // 원본 이미지를 복원
    
    			resize(m_matImage, m_matImage, Size(200, 200));
    
    			//imshow("img_edge", m_matImage);
    
    			CreateBitmapInfo(m_matImage.cols, m_matImage.rows, m_matImage.channels() * 8);
    			DrawImage();
    		}
    		else {
    			AfxMessageBox(_T("복원할 수 없음"), MB_ICONSTOP);
    			m_chEdge.SetCheck(BST_UNCHECKED);
    		}
    	}
    }



결과




참고자료

[OpenCV] 캐니 에지 검출(Canny edge detection)

0개의 댓글