[Intel] 절차/객체 지향 프로그래밍
인텔 엣지 AI S/W 아카데미 4기 - '절차/객체 지향 프로그래밍' 수업 및 프로젝트 정리
Apr 21, 2024
목차
절차 지향 프로그래밍
1. 소프트웨어 배포 생명 주기
본 프로젝트는 아래의 소프트웨어 배포 생명 주기에 따라 진행 되었습니다.
- 알파(Alpha)
- 알파 단계는 초기 개발 단계로, 핵심 기능은 구현되어 있지만 많은 버그가 존재할 수 있습니다.
- 베타(Beta)
- 베타 단계는 알파 단계 이후로, 기능은 대부분 구현되어 있지만 여전히 버그가 있을 수 있습니다.
- RC(Release Candidate)
- RC 단계는 베타 단계 이후로, 대부분의 버그가 수정되어 출시에 가까운 상태입니다.
- 프리뷰(Preview)
- 프리뷰 단계는 RC 이후로, 최종 버전을 미리 공개하는 단계입니다.
- 릴리즈(Release)
- 릴리즈 단계는 정식 버전으로, 일반 사용자에게 배포되는 단계입니다.
- RTM(Release to Manufacturing), GA(General Availability), 커뮤니티 버전 등이 있습니다.
- 패치(Patch)
- 패치는 릴리즈 버전에서 발견된 중요 버그를 수정하는 작은 업데이트입니다.
- 업데이트(Update)는 새로운 기능 추가 및 버그 수정을 포함하는 중간 규모의 업데이트입니다.
- 서비스 팩(Service Pack)은 대규모 업데이트로, 여러 개의 패치와 업데이트를 하나로 묶은 것입니다.
2. Window API 프로그래밍
- Windows API는 Microsoft에서 제공하는 Windows 운영 체제의 기능을 사용할 수 있게 해주는 인터페이스입니다.
이번 미니 프로젝트 Version 1에서는 간단한 Windows API 함수를 사용하여 DOS 창을 통해 이미지를 Windows 화면에 직접 출력하는 방식으로 구현하였습니다.
- 반전 효과 적용 화면
3. 소스 코드 및 미니 프로젝트 Version 1 발표 자료
객체 지향 프로그래밍
1. MFC
- MFC(Microsoft Foundation Classes)는 마이크로소프트에서 제공하는 C++ 라이브러리입니다. 윈도우 응용 프로그램을 개발할 때 사용되며, GUI(Graphic User Interface) 프로그래밍을 쉽게 할 수 있게 해줍니다.
- 주요 특징
- 윈도우 메시징과 이벤트 처리를 간단히 할 수 있습니다.
- 다양한 UI 컨트롤(버튼, 메뉴, 툴바 등)을 쉽게 추가할 수 있습니다.
- 문서/뷰 아키텍처를 통해 데이터와 UI를 분리하여 개발할 수 있습니다.
- OLE, 데이터베이스 프로그래밍 등 다양한 기능을 지원합니다.
- Visual C++ 통합 개발 환경을 지원하여 GUI 기반 개발이 가능합니다.
- MFC 표기법
- 헝가리안 표기법
- 변수나 함수 이름에 데이터 형식이나 유형에 대한 정보를 접두사로 붙이는 방식
iCount
- 정수형 변수 Count- 클래스는 모두 C로 시작한다.
- 여러 단어가 하나의 클래스 이름일 경우 각 단어별로 첫 글자를 대문자로 표기한다.
- 맴버 변수는 m_으로 시작하고, 맴버 변수는 대문자로 시작한다.
- 전역 함수는 Afx라는 접두어가 붙는다.
- 최근에는 .NET이나 더 가벼운 라이브러리를 사용하는 추세라고 합니다.
이번 미니 프로젝트 Version 2에서는 MFC를 사용하여 UI를 구현하였습니다.
2. MFC 시작하기
먼저 Visual Studio을 실행한 후, 새 프로젝트를 생성해 줍니다. Visual Studio를 설치 시 MFC를 선택해야만 아래와 같이 ‘MFC 앱’이 활성화됩니다.
- 프로젝트 이름을 입력한 후, 애플리케이션 종류와 프로젝트, 비주얼 스타일을 선택합니다.
- 문서 템플릿 속성에서, 파일 확장명을 입력합니다. 저는 Gray scale의 경우 .raw로, Color scale의 경우 .jpg로 설정했습니다.
프로젝트가 생성되면 먼저 이미지 처리에 필요한 유틸리티 함수들이 필요합니다. MFC에서는 함수의 재정의를 통해 문서 처리 및 그래픽 렌더링 기능을 사용자가 정의할 수 있습니다.
- 표시된 버튼을 클릭한 뒤, 원하는 기능의 함수를 선택해 Add 하고 기능을 구현합니다.
- 이러한 방식으로 Doc 클래스의
OnOpenDocument()
와OnSaveDocument()
, View 클래스의OnDraw()
함수를 재정의하여 사용했습니다.
- 프로젝트가 생성되면, 각 기능에 해당하는 함수와 변수를 추가해주면 됩니다.
- 참고로 변수나 함수의 이름, 매개변수 등 잘못 설정할 경우 다시 선언하거나 사용 하지 않는 방법을 사용해야 합니다.
- 보이지 않는 기능은 Doc.cpp에, 보이는 기능은 View.cpp에 구현합니다.
이제 Doc 클래스에 영상 처리 알고리즘을 수행하는 함수를 추가해야 합니다.
- 함수 이름과 반환 형식, 매개 변수 등을 입력한 뒤 영상처리 기능을 구현해 줍니다.
영상 처리 알고리즘을 구현해 기능들을 만들었다면, 그러한 기능들과 여러 옵션을 선택하는 화면이 필요하겠죠?
- 리소스 파일의 Menu에서 Main Menu를 찾아 선택하고, 기능을 선택할 수 있는 화면을 구성해줍니다.
- 각 기능 메뉴의 속성에서 ID를 설정한 후, 이벤트 처리기를 View 클래스에 추가합니다.
- 그러면 View.cpp에 함수가 추가되는데, 아래의 코드를 통해 기능을 수행합니다.
// 영상을 반전시키는 함수 void CColorImageProcessingView::OnReverseImage() { // 문서 클래스로부터 문서 포인터를 가져옵니다. CColorImageProcessingDoc* pDoc = GetDocument(); // 문서 포인터가 유효한지 확인합니다. ASSERT_VALID(pDoc); // 문서의 OnReverseImage() 함수를 호출하여 실제 영상 반전 작업을 수행합니다. pDoc->OnReverseImage(); // 뷰 영역을 무효화하여 반전된 영상을 다시 그립니다. Invalidate(TRUE); }
이러한 방식으로 View에서 Doc을 호출해 수행하는 방식은 MFC의 문서/뷰 아키텍처에 따라 객체 지향 원칙을 지키기 위한 것입니다.
- 입력 대화 상자
- MFC에서는 입력 대화 상자를 통해 영상처리 기능들을 수행할 때, 사용자에게 입력을 받아 처리할 수 있습니다.
- Edit Control은 사용자에게 값을 입력받을 수 있습니다.
- 범주를 ‘값’으로 설정한 후 이름과 형식을 입력합니다. ‘기타’에서 최대값과 최소값 또한 지정할 수 있습니다.
- Radio Button은 값을 입력받는 것이 아닌, 선택지를 제공할 수 있습니다.
- 도구 상자에서 여러 개의 Radio Button을 가져와 Dialog에 놓습니다. 그리고 Dialog 상자 클래스를 추가 해줍니다.
Ctrl + D
를 입력해 첫 번째 라디오 버튼을 확인할 수 있습니다.- Dialog 상자.cpp 파일에서, 생성자에 인덱스 변수를 0으로 초기화 합니다.
- 밑의
DoDataExchange()
함수에 아래의 코드를 추가해 줍니다.
먼저 리소스 파일의 Dialog에서, 삽입을 눌러줍니다.
Edit Control
도구 상자에서 텍스트와 Edit Control를 가져와 Dialog에 놓습니다. 그리고 Dialog 상자 클래스를 추가해줍니다.
Dialog 상자 클래스를 생성했다면, Edit Control의 변수를 추가해줍니다.
Dialog 클래스와 변수 생성이 완료되면, Doc.cpp에 해당 Dialog 클래스를 include 해서 입력받은 값을 처리할 수 있습니다.CConstantF dlg; if (dlg.DoModal() != IDOK) return; double sigma = (double)dlg.m_constant_f;
Radio Button
Dialog 상자 클래스를 생성했다면, 첫 번째 라디오 버튼의 ‘그룹’을 True로 설정해줍니다.
첫 번째 라디오 버튼에UINT
형의 인덱스 변수를 추가해 줍니다.
CConstantConv ::CConstantConv (CWnd* pParent /*=nullptr*/) : CDialog(IDD_CONSTANT_CONV, pParent) { m_radio_index = 0; // 인덱스 변수 }
void CConstantConv ::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); // 라디오 버튼의 선택 상태를 m_radio_index 멤버 변수와 연결합니다. DDX_Radio(pDX, 첫번째라디오버튼ID, (int&)m_radio_index); // 이 부분 추가 }
이제 Doc.cpp에 해당 Dialog 클래스를 include 해서 경우에 따라 처리할 수 있습니다.CConstantConv btn; if (btn.DoModal() != IDOK) return; if (btn.m_radio_index == 0) // 첫 번째 라디오 버튼을 선택했을 경우 size = 3; else if (btn.m_radio_index == 1) // 두 번째 라디오 버튼을 선택했을 경우 size = 5; else if (btn.m_radio_index == 2) // 세 번째 라디오 버튼을 선택했을 경우 size = 7; else if (btn.m_radio_index == 3) // 네 번째 라디오 버튼을 선택했을 경우 size = 9;
3. 소스 코드 및 미니 프로젝트 Version 1(spin-off), Version 2 발표 자료
Share article