제목 : 미디어정보처리프로그래밍실습모음 일시 : 2002. 6. 15 작성자 : 성용철학번 : 한남대학교정보통신멀티미디어공학부 ( 전자정보통신전공 )
미디어정보처리프로그래밍실습숙제설명 1.256 X 256 grayscale 의디스플레이프로그램 Resource View 의 menu item 에서 Display 밑에 Raw gray 라마든다음에그림과같이 ID 와 Caption 을넣는다. CTestView 클래스에다음과같이함수를생성한다. void CTestView::OnOpen() // TODO: Add your command handler code here CTestDoc* pdoc=getdocument(); ASSERT_VALID(pDoc); pdoc->choice=1; pdoc->doubleload(); //OnDraw함수에서출력하기위한변수선택 //raw 그레이스케일을읽어들이기위한함수 Invalidate(FALSE); CTestDoc 클래스에그림을읽어들이기위한함수를만든다. void CTestDoc::DoubleLoad() //AfxMessageBox("Gray Scale 을선택하세요."); CFileDialog dlg(true); if(dlg.domodal()==idok) CFile file; file.open(dlg.getfilename(), CFile::modeRead); file.read(m_openimg,sizeof(m_openimg)); file.close();
2.256 X 256 Color scale 을읽어들이기 그림과같이 CTestView에컬러를읽어들이기위한함수를만든다. void CTestView::OnCopen() // TODO: Add your command handler code here CTestDoc* pdoc=getdocument(); ASSERT_VALID(pDoc); pdoc->choice=2; pdoc->doubledcload(); Invalidate(FALSE); // 컬러를읽어들이기위한함수 도큐먼트클래스에다음과같은함수를만든다. void CTestDoc::DoubledCLoad() AfxMessageBox("Color 를선택하세요. "); CFileDialog dlg(true); if(dlg.domodal()==idok) CFile file; file.open(dlg.getfilename(), CFile::modeRead);
file.read(m_opencimg,sizeof(m_opencimg)); file.close(); 뷰클래스의 Ondraw함수의코드부분이다. choice==1은 GrayScale일경우이고 Choice==2는 Color일경우이다. if(pdoc->choice==1) for (int y=0;y<256;y++) for(int x=0;x<256;x++) pdc->setpixel(x,y,rgb(pdoc->m_openimg[y][x], pdoc->m_openimg[y][x], pdoc->m_openimg[y][x])); if (pdoc->choice==2) for (int y=0;y<256;y++) int z=0; for(int x=0;x<256;x++) z+=3; pdc->setpixel(x,y,rgb(pdoc->m_opencimg[y][z], pdoc->m_opencimg[y][z+1], pdoc->m_opencimg[y][z+2])); 3.256*256 scale 의그레이영상을읽어들이고이영상에일정한양의정수를더한합의영상을처리하고원영상과함께디스플레이하는프로그램리소스뷰에다음과같이다이얼로그박스를만든다
다이얼로그박스에대한클래스를생성한다. View 클래스에 OnSumConst 함수를만든다음다음과같이코딩한다. void CTestView::OnSumConst() // TODO: Add your command handler code here CTestDoc* pdoc=getdocument(); ASSERT_VALID(pDoc); pdoc->choice=3; int Temp; UpdateData(); if(m_dlgconst.domodal()==idok) // 다이얼로그박스에대한이벤트 Temp=m_dlgConst.m_Const; int data=0; for(int x=0; x<256; x++) for(int y=0; y<256; y++) data=pdoc->m_openimg[x][y] + Temp; if(data>255) pdoc->m_resultimg[x][y]=255; else pdoc->m_resultimg[x][y]=data; Invalidate(FALSE);
4. 두영상을더하는처리와그결과를원영상과함께출력하는프로그램 뷰클래스에다음과같이 OnSumImage 함수를만든다. void CTestView::OnSumImage() // TODO: Add your command handler code here int data=0; CTestDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); pdoc->secfileload(); // 두개의파일을순서대로불러들이기위한코드 pdoc->choice=4; for(int x=0; x<256; x++) for(int y=0; y<256; y++) pdoc->m_imagebuffer1[x][y]+pdoc->m_imagebuffer2[x][y]; if(data>255) pdoc->m_resultimg[x][y]=255; else pdoc->m_resultimg[x][y]=data; pdoc->m_openimg[x][y]=data; Invalidate(FALSE); 도큐먼트쿨래스에파일을읽어들이기위한 SecFileLoad() 함수를만든다. void CTestDoc::SecFileLoad() AfxMessageBox("Select First Image"); CFileDialog dlg(true); if(dlg.domodal()==idok) CFile file; file.open(dlg.getfilename(), CFile::modeRead); file.read(m_imagebuffer1,sizeof(m_imagebuffer1)); file.close();
//Second Image Load AfxMessageBox("Select second Image"); CFileDialog dlg2(true); if(dlg2.domodal()==idok) CFile file; file.open(dlg2.getfilename(), CFile::modeRead); file.read(m_imagebuffer2,sizeof(m_imagebuffer2)); file.close(); 5. 엠보싱효과 3X3 컨볼루션마스크를읽어들이는다이얼로그박스를만들고정수데이터를입력받아엠보싱효과를내는프로그램다이얼로그박스를다음과같이디자인한다. edit 박스에대해변수를설정한다. ClassWizard를통해새로운클래스로등록한다. ClassWizard에서 edit 박스를통해입력받는변수에대한속성과변수명설정한다. 뷰클래스에다음과같이코딩한다. void CTestView::OnEmbossing() CTestDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); int t1,t2; UpdateData(); if(m_ems.domodal()==idok) t1=m_ems.m_embos1,t2=m_ems.m_embos2;
if(t1==0) t1=-1,t2=1; int centervalue1=0; int sum=0; unsigned char m_tmpimg[258][258]; int mask1[3][3]= t1,0,0, 0,0,0, 0,0,t2; for(int k=1; k<257; k++) for(int l=1; l<257; l++) m_tmpimg[k][l]=pdoc->m_openimg[k-1][l-1]; for(int row=0; row<256; row++) for(int column=0; column<256; column++) for(int i=0; i<3; i++) for(int j=0; j<3; j++) centervalue1+=m_tmpimg[i+row][j+column]*mask1[i][j]; sum=abs(centervalue1+= 128); if(sum>255)sum=255; pdoc->m_resultimg[row+1][column+1]=(unsigned char)sum; centervalue1=0; sum=0; UpdateData(FALSE); pdoc->choice=4; Invalidate(FALSE);
6. 소벨윤곽선검출기 다이얼로그박스에다음과같이디자인하고새로운클래스를추가한다. 각에디트박스마다변수를할당한다. 뷰클래스에다음과같이코딩한다. void CTestView::OnSobel() // TODO: Add your command handler code here CTestDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); pdoc->sobel(); // 소벨연산을하는함수이다. pdoc->choice=3; Invalidate(FALSE); 도큐먼트클래스에다음과같이코딩한다 void CTestDoc::Sobel() int e1,e2,e3,w1,w2,w3; if(m_dlgsobel.domodal()==idok) e1=m_dlgsobel.m_de1, e2=m_dlgsobel.m_de2,e3=m_dlgsobel.m_de3, w1=m_dlgsobel.m_dw1, w2=m_dlgsobel.m_dw2,w3=m_dlgsobel.m_dw3 ; if (e1==0) // 상수를입력하지않을경우디폴트로하기위한처리 e1=1, e2=2, e3=1,w1=1,w2=2,w3=1; int centervalue1=0; int centervalue2=0; int sum=0; unsigned char m_tmpimg[258][258];
int mask1[3][3]= 0-e1,0,e1, 0-e2,0,e2, 0-e3,0,e3; int mask2[3][3]= w1,w2,w3, 0,0,0, 0-w1,0-w2,0-w3; for(int k=1; k<257; k++) for(int l=1; l<257; l++) m_tmpimg[k][l]=m_openimg[k-1][l-1]; for(int row=0; row<256; row++) for(int column=0; column<256; column++) for(int i=0; i<3; i++) for(int j=0; j<3; j++) centervalue1 += m_tmpimg[i+row][j+column]*mask1[i][j]; centervalue2 += m_tmpimg[i+row][j+column]*mask2[i][j]; sum=abs(centervalue1)+abs(centervalue2); if(sum>255)sum=255; m_resultimg[row+1][column+1]=(unsigned char)sum; centervalue1=0; centervalue2=0; sum=0;
7. 샤프닝 위와동일한과정을거쳐새로운클래스와다이얼로그를만든다, 뷰클래스에샤프닝에대한함수를만든다. void CTestView::OnShrp() // TODO: Add your command handler code here CTestDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); pdoc->sharp(); pdoc->choice=4; Invalidate(FALSE); 도큐먼트클래스에샤프닝을구현할코드를만든다. void CTestDoc::Sharp() int a=0,b=0,c=0,d=0,e=5,f=0,g=0,h=0,i=0 ; int sum=0; if(m_sharp.domodal()==idok) a=m_sharp.m_dlgsh1, b=m_sharp.m_dlgsh2, c=m_sharp.m_dlgsh3, d=m_sharp.m_dlgsh4, e=m_sharp.m_dlgsh5, f=m_sharp.m_dlgsh6, g=m_sharp.m_dlgsh7, h=m_sharp.m_dlgsh8, i=m_sharp.m_dlgsh9; if(e==0) b=-1,d=-1,e=5,f=-1,h=-1;
int mask[3][3]= a,b,c, d,e,f, g,h,i; for(int row=0; row<255; row++) for(int column=0; column<255; column++) for(int i=0; i<3; i++) for(int j=0; j<3; j++) sum += m_openimg[i+row][j+column]*(mask[i][j]); if(sum<0)sum=0; else if(sum>255)sum=255; m_resultimg[row+1][column+1]=(unsigned char)sum; sum=0; 8. Affine 변환을수행하는프로그램전의과정들과같이다이얼로그와새로운클래스를추가하고변수를할당한다.
뷰클래스에다음과같이코딩한다. void CTestView::OnAffine() // TODO: Add your command handler code here CTestDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); pdoc->affine(); zoom=1; Invalidate(FALSE); 도큐먼트클래스에다음과같이코딩한다. void CTestDoc::Affine() int Shift_X=0,Shift_Y=0,Roat=0,Size_X=0,Size_Y=0; if(dlgaffine.domodal()==idok) Shift_X=dlgAffine.m_Aff1, Shift_Y=dlgAffine.m_Aff2, Roat=dlgAffine.m_Aff3,Size_X=dlgAffine.m_Aff4, Size_Y=dlgAffine.m_Aff5; // 회전 if(roat>0) double i=0,j=0,m=0,n=0,x=0,y=0; int y=0,x=0,left=0,right=0; double seta=0,pi=3.1415926535; double in,k; in=roat; if(in==360) // 입력되는각이 360도일경우 k=180/in; else if (in>180) // 입력되는각이 180도를넘을경우 k=(-180/(in-180)); else // 입력되는각이 180도가안되는경우
k=180/in; seta=pi/k; for(y=0; y<256; y++) for(x=0; x<256; x++) i=-1*((y-128)*sin(seta))+128; j=(x-128)*cos(seta); X=(i+j); if(x>255)x=255; if(x<0)x=0; m=((x-128)*sin(seta))+128; n=(y-128)*cos(seta); Y=(m+n); if(y>255)y=255; if(y<0)y=0; m_resultimg[(int)y][(int)x]=m_openimg[y][x]; // 확대 if(size_x>0) int i=0,j=0,y=0,x=0,sum=0; int m_inx=size_x, m_iny=size_y ; for(y=0; y<256; y++) for(x=0; x<256; x++) i=y*m_iny; j=x*m_inx; m_scaleimg[i][j]=m_resultimg[y][x];
//*/////////////// 평균값을이용한보간법 /////////////////// //step1 y=0; x=0; for(i=1; i<512; i+=2) for(j=1; j<512; j+=2) sum+=m_scaleimg[y][(x)]; sum+=m_scaleimg[y][(x)+2]; sum+=m_scaleimg[y+2][(x)]; sum+=m_scaleimg[y+2][(x)+2]; sum=sum/4; m_scaleimg[i][(j)]=sum; sum=0; x+=2; x=0; y+=2; //step2 y=0; x=0; for(i=0; i<512; i+=2) for(j=1; j<512; j+=2) sum+=m_scaleimg[y][(x)]; sum+=m_scaleimg[y][(x)+2]; sum=sum/2; m_scaleimg[i][(j)]=sum; sum=0; x+=2; x=0; y+=2; //step3 y=0; x=0; for(j=0; j<512; j+=2) for(i=1; i<512; i+=2) sum+=m_scaleimg[y][(x)];
sum+=m_scaleimg[y+2][(x)]; sum=sum/2; m_scaleimg[i][(j)]=sum; sum=0; y+=2; y=0; x+=2; 9.PPM Image file의 Load /Store 뷰클래스에다음과같이코딩한다. void CTestView::OnGet_Result() // TODO: Add your command handler code here CTestDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); pdoc->ppmload(); pdoc->get_ppm(); pdoc->choice=5; Invalidate(FALSE); 도큐먼트크래스에파일을읽어오는함수와파일의헤더와이미지를분리하여정보를얻어내는부분을코딩한다. void CTestDoc::PpmLoad() //PPM 이미지파일을읽어온다. CFileDialog dlg(true); if(dlg.domodal()==idok) CFile file; file.open(dlg.getfilename(), CFile::modeRead); file.read(m_opentotal,sizeof(m_opentotal)); file.close(); void CTestDoc::Get_PPM() //PPM 파일의영상정보를갖고온다.
int temp1=m_opentotal[3]-'0'; int temp2=m_opentotal[4]-'0'; int temp3=m_opentotal[5]-'0'; m_x=(temp1*100)+(temp2*10)+temp3; //x축픽셀값 int temp4=m_opentotal[7]-'0'; int temp5=m_opentotal[8]-'0'; int temp6=m_opentotal[9]-'0'; m_y=(temp4*100)+(temp5*10)+temp6; //y축픽셀값 int t=15; for(int y=0; y<m_y; y++) // 이미지부분에대한정보추출 for (int x=0; x<m_x*3; x+=3) m_openppm[y][x]=m_opentotal[t++]; m_openppm[y][x+1]=m_opentotal[t++]; m_openppm[y][x+2]=m_opentotal[t++]; 뷰문서의 OnDraw() 함수에다음을코딩한다. if(choice==5) int RV=0,GV=1,BV=2; for (int y=0;y<pdoc->m_y;y++) for(int x=0;x<pdoc->m_y;x++) pdc->setpixel(x,y,rgb(pdoc->m_openppm[y][rv+=3], pdoc->m_openppm[y][gv+=3], pdoc->m_openppm[y][bv+=3])); RV=0;GV=1;BV=2; pdoc->store_result();