8/25/2011

Shape from Shading Matlab and C++(MFC) source

Created Date : 2007.8
Language : Matlab / C++(MFC)
Tool : Matlab / Visual C++ 6.0
Library & Utilized : - / OpenGL
Reference :  Shape from Shading, Photometric Stereo reference
etc. : -

Shading Source Images

Depth Image                            Normal Vector

Shading Source Images

Depth Image                            Normal Vector


Shading Source Images

Depth Image                            Normal Vector


This program make 3D shape using several different source of light.
The result is normal vector figure and 3D depth image.
This method is alternatively called as Photometric stereo.


You can download entire source code. <Matlab> < C++(MFC) >





If you have good idea or advanced opinion, please reply me. Thank you
(Please understand my bad english ability. If you point out my mistake, I would correct pleasurably. Thank you!!)



---------------------------------------------------------------------------

6개의 광원과 모델을 이용하여 3D 형상으로 복원하는 프로그램
3D 형상은 각 픽셀의 depth와 normal 방향을 계산하여 드로잉한다.
Photometric stereo 기법 이라고도 함.

여기서 전체 소스를 다운 받을 수 있습니다. <Matlab> < C++(MFC) >


좋은 의견 어떤 글이든 답변 남겨주세요

감사합니다.

8/24/2011

Canny Edge C++ source / 캐니 에지 프로그램 소스

Created Date : 2007.9
Language : C++
Tool : Visual Studio C++ 6.0
Library & Utilized : -
Reference :  Canny Edge's Paper and Reference tutorial
etc. : -







1. Input
First, enter the file name of bmp format.
And input parameters. (sigma value, Hysteresis low, high value. Default values are 1.0, 20, 80 respectively).

2. Results
3 files saved in your folder that direction is same with exe file location.
Origin Image

One is differential of Gaussian image and the others are NonMax Supression and Hysteresis image.

You can download entire source code.
< source code >




If you have good idea or advanced opinion, please reply me. Thank you
(Please understand my bad english ability. If you point out my mistake, I would correct pleasurably. Thank you!!)------------------------------------------------------

1. DOG 부분
마스크를 만든다.
마스크를 이미지에 회선하면서 컨볼루션한다. 한번 회선할 때 가로, 세로에 대하여 모두 연산함 2. NonMax Supression 부분
에지의 방향의 노말방향에 대하여 좌우 픽셀의 밝기보다 큰지 작은지를 조사한다.
∴단 기존의 방법으로 인접한 같은 픽셀값은 최대값을 찾지 못하고 손실되기 때문에, 인접한 픽셀값을 만났을 때는 자기 자신을 -1하여 값을 낮춘다.
예) 55 100 100 100 55 -> 55 99 100 100 55 -> 55 99 99 100 55 -> 0 0 0 100 0

3. Hysteresis Thresholding 부분
에지의 방향에 대하여 픽셀은 추적하면 에지의 방향과 픽셀의 위치가 다르기 때문에 끊어지는 현상이 자주 발생하므로 에지의 방향을 이용하지 않고 잔디에 불을 붙여 연결된 픽셀을 추적하는 GlassFire 방법을 사용하여 High값과 Low값의 개념을 그대로 적용하여 사용한다.
tempImg라는 임시 버퍼를 하나 만들어 방문했던 픽셀의 위치에 대하여 표시를 해둔다.
danji()함수는 재귀호출로 인접한 픽셀을 모두 검색해준다.
danji()함수는 8방향에 대하여 Low값보다 큰 픽셀에 대하여 불을 붙이듯 재귀호출을 하여 선을 이어간다.

▣ 인터페이스 설명
실행 파일을 실행하여 파일명, 시그마값, Hysteresis의 low, high값을 입력한다.
결과는 DOG.bmp, NonMax.bmp, Hysteresis.bmp 로 세 개의 이미지가 저장된다.

여기서 전체 파일을 받을 수 있습니다.
< source code >

좋은 의견 어떤 글이든 답변 남겨주세요


DOG

NonMax

Hysteresis



8/23/2011

AdaBoost Matlab source for understanding easy/ 아다부스트 알고리즘을 쉽게 이해할 수 있는 매트랩 소스


Created Date : 2006.7
Language : Matlab
Tool : Matlab
Library & Utilized : -
Reference :  {Paul Viola & Michael Jone}'s Paper
etc. : -




This source is made for AdaBoost algorithm understanding easy, when I prepared master's thesis.
First picture is the window for inputting data. If you click left button, positive(+1) data is inputted and right button is for inputting negative(-1) data.
After inputting all data, enter the any then boosting start.
Second image is the result of learning. All data(in this case, position is data) is determined as positive(+1) or negative(-1).

You can download this source <here>.

Plz reply your opinion.
Thank you.

(Please understand my bad english ability. If you point out my mistake, I would correct pleasurably. Thank you!!)


------------------------------------------------------

AdaBoost 작동 원리를 심플하게 파악할수 있는 매트랩 소스
AdaBoostMatlab 매트랩 파일을 열어서 - f5키 실행
Figure 새창이 떳을때 왼쪽 클릭(+1 클래스), 오른쪽 클릭 (-1 클래스)으로
평면에 학습 데이터 샘플을 지정해준다. 많이 해도 상관없음
학습데이터 샘플을 원하는 만큼 만든 다음 엔터키를 누르면 부스팅 시작
학습이 끝난다음 평면에서 모든 좌표에 대하여 +1 클래스인지 -1 클래스인지를 판단하여 색으로 표현한다. 이것이 학습에 대한 검출 끝.
AdaBoostMatlab.m 말고 다른 파일들은 그냥 만들면서 테스트한 파일들인데 참고하시고 아다부스트에 필요하지는 않습니다.

여기서 이 소스를 다운 받을 수 있습니다. <here>

좋은 의견이나 개선사항 어떤 글이든 답변 남겨주세요.
감사합니다.

8/22/2011

Mini PhotoShop / Image Processing Tool / C++ source (MFC) / 미니 포토샵, 이미지 프로세싱 툴


Created Date : 2003.3
Language : C/C++
Tool : Microsoft Visual C++ 6.0 (MFC)
Library & Utilized : -
Reference :  Simplified approach to image prcessing book -Randy Crane-
etc. : Bmp Image Files







Many ages ago, when I studied image processing firstly, I made this program for training programming skill and studying  image processing.

This program include variety image processing functions.
For example

Filter function - blur,highpass, median, embossing, edge gaussian noise, morphology, the window that support preview function and the value of mask.
Geometry function - flip, rotation, zoom in/out
Channel split - RGB, HSI, CMYK, YIQ, YUW, YUV, YCbCr, the window that support preview function.
Color adjustment - Contrast, Brightness, HSI, Gamma, Red-Green tint, Reference, colorfulness
Histogram - binary, logarithm, auto contrast strech, end in contrast stretch.
etc - undo,redo function, skin color detection, labeling

You can download entire source code -> <Here>

Plz reply your opinion.
Thank you.

(Please understand my bad english ability. If you point out my mistake, I would correct pleasurably. Thank you!!)


-----------------------------------------------------


처음 영상처리 공부를 시작했을 때 프로그래밍과 이미지 처리 방법을 공부하기 위해 만든 프로그램 입니다.

이 프로그램은  bmp 파일포맷을 자유롭게 다룰수 있는 클래스를 제작하여 다음과 같은 여러가지 이미지 처리 기능을 구현했습니다.
필터기능 - blur,highpass, median, embossing, edge gaussian noise, morphology.
필터결과와 마스크값을 미리보기 기능창.
이미지조작 - 플립, 반전, 회전, 확대, 축소
체널 분리 - RGB, HSI, CMYK, YIQ, YUW, YUV, YCbCr, 분리된 채널을 한눈으로 볼수있는 기능창.
색조절 - Contrast, Brightness, HSI, Gamma, Red-Green tint, Reference, colorfulness.
히스토그램 - 이진화, logarithm, auto contrast strech,end in contrast stretch.
기타 - undo,redo기능 살색추출, 라벨링.

이 프로그램은 여기에서 받을 수 있습니다. <Here>

개선 사항이나 좋은 의견 있으시면 답변 주세요.
감사합니다.


8/21/2011

Two Image mosaic (paranoma) based on SIFT / C++ source (OpenCV) / SIFT 특징 추출기를 이용한 두장의 영상을 모자익(파라노마) 영상으로 만들기

Created Date : 2011.2
Language : C/C++
Tool : Microsoft Visual C++ 2010
Library & Utilized : OpenCV 2.2
Reference : Interent Reference
etc. : 2 adjacent images


two adjacent iamges

Feature extraction by Surf(SIFT)

Feature matching

Mosaic (paranoma)

This program is conducted as follow process.
First, the program finds feature point in each image using SURF.
->cvExtractSURF
Second, feature points on each images is matched by similarity.
->FindMatchingPoints
Third, We get the Homography matrix.
->cvFindHomography
Last, we warp the image for attaching into one image.
->cvWarpPerspective

You can download source here.
If you have good idea or advanced opinion, please reply me.
Thank you.

-----------------------------------------------------------------------------

이웃된 두 장의 영상을 입력 받아 하나의 모자이크 영상(파라노마)으로 만든다.
특징 추출 및 비교 방법 : suft ->cvExtractSURF
특징 매칭 방법 : FindMatchingPoints
호모그라피 행렬 구하기 : cvFindHomography
영상 모자이크 방법 : warpping

전체 소스 코드는 여기서 받을 수 있습니다.
https://github.com/MareArts/Two-Image-mosaic-paranoma-based-on-SIFT
개선 사항이나 좋은 의견 있으시면 답변 주세요.
감사합니다.



#include < iostream>
#include < cv.h>
#include < cxcore.h>
#include < highgui.h>


using namespace std;

typedef struct MATCH_PAIR
{
 int nA;
 int nB;
} MATCH_PAIR;


void MergeImages(IplImage* Image1, IplImage* Image2, IplImage* dstImage);
int FindMatchingPoints(const CvSeq* tKeypoints, const CvSeq* tDescriptors, const CvSeq* srcKeypoints, const CvSeq* srcDescriptors, int descriptor_size, MATCH_PAIR *pMatchPair);
int FindNearestPoints(const float* pA, int laplacian, const CvSeq* srcKeypoints, const CvSeq* srcDescriptors, int descriptor_size);

void main()
{
 
 ///////////////////////////////////////////////////////////////////////////////////////////
 //load two image
 //first
 IplImage *T1Img, *mT1Img;
 if((T1Img = cvLoadImage("T1.jpg", CV_LOAD_IMAGE_GRAYSCALE)) == NULL)
 {
  printf("A Img open error\n");
  return ;
 }
 //
 mT1Img = cvCreateImage(cvSize(T1Img->width, T1Img->height),T1Img->depth, 3);
 cvCvtColor(T1Img, mT1Img, CV_GRAY2BGR);
 
 // second
 IplImage* T2Img, *mT2Img;
 if((T2Img = cvLoadImage("T2.jpg", CV_LOAD_IMAGE_GRAYSCALE)) == NULL)
 {
  printf("B Img open error\n");
  return ;
 }
 //
 mT2Img = cvCreateImage(cvSize(T2Img->width, T2Img->height),T2Img->depth, 3);
 cvCvtColor(T2Img, mT2Img, CV_GRAY2BGR);

 //make window
 cvNamedWindow("Origin T1 Img", 1);
 cvNamedWindow("Origin T2 Img", 1);
 
 cvShowImage("Origin T1 Img", T1Img);
 cvShowImage("Origin T2 Img", T2Img);
 ///////////////////////////////////////////////////////////////////////////////////////////


 ///////////////////////////////////////////////////////////////////////////////////////////
 //surf 
 CvMemStorage* storage =cvCreateMemStorage(0);
 CvSURFParams params = cvSURFParams(300, 0);

 //T1 Img
 CvSeq *T1_Keypoints = NULL;
 CvSeq *T1_Descriptors = NULL;
 cvExtractSURF(T1Img, NULL, &T1_Keypoints, &T1_Descriptors, storage, params);
 printf("T1 Img - Keypoint: %d\n", T1_Keypoints->total);
 printf("T1 Img - Descriptors : %d\n", T1_Descriptors->total);

 //T2 Img
 CvSeq *T2_Keypoints = NULL;
 CvSeq *T2_Descriptors = NULL;
 cvExtractSURF(T2Img, NULL, &T2_Keypoints, &T2_Descriptors, storage, params);
 printf("T2 Img - Keypoints : %d\n", T2_Keypoints->total);
 printf("T2 Img - Descriptors : %d\n", T2_Descriptors->total);
 
 //draw feature1
 CvSURFPoint* surf1;
 for(int i = 0; i <  (T1_Keypoints ? T1_Keypoints->total : 0); i++ )
    {
  surf1 = (CvSURFPoint*) cvGetSeqElem(T1_Keypoints, i);
  int r = surf1->size/2;
  cvCircle( mT1Img, cvPoint(surf1->pt.x, surf1->pt.y) , r, CV_RGB(0,255,0));
  cvLine( mT1Img, cvPoint(surf1->pt.x + r, surf1->pt.y + r), cvPoint(surf1->pt.x - r, surf1->pt.y - r), CV_RGB(0,255,0));
        cvLine( mT1Img, cvPoint(surf1->pt.x - r, surf1->pt.y + r), cvPoint(surf1->pt.x + r, surf1->pt.y - r), CV_RGB(0,255,0));
    }

 //draw feature2
 CvSURFPoint* surf2;
 for(int i = 0; i <  (T2_Keypoints ? T2_Keypoints->total : 0); i++ )
    {
  surf2 = (CvSURFPoint*) cvGetSeqElem(T2_Keypoints, i);
  int r = surf2->size/2;
  cvCircle( mT2Img, cvPoint(surf2->pt.x, surf2->pt.y) , r, CV_RGB(0,255,0));
  cvLine( mT2Img, cvPoint(surf2->pt.x + r, surf2->pt.y + r), cvPoint(surf2->pt.x - r, surf2->pt.y - r), CV_RGB(0,255,0));
        cvLine( mT2Img, cvPoint(surf2->pt.x - r, surf2->pt.y + r), cvPoint(surf2->pt.x + r, surf2->pt.y - r), CV_RGB(0,255,0));
    }

 //surf feature draw
 cvNamedWindow("Surf T1 Img", 1);
 cvNamedWindow("Surf T2 Img", 1);
 
 cvShowImage("Surf T1 Img", mT1Img);
 cvShowImage("Surf T2 Img", mT2Img);
 ///////////////////////////////////////////////////////////////////////////////////////////
 

 ///////////////////////////////////////////////////////////////////////////////////////////
 //Image merging
 IplImage* MergeImg = cvCreateImage(cvSize(T1Img->width+T2Img->width, T1Img->height), IPL_DEPTH_8U, 3);
 MergeImages(T1Img, T2Img, MergeImg); 
 ///////////////////////////////////////////////////////////////////////////////////////////


 ///////////////////////////////////////////////////////////////////////////////////////////
 //matching
 MATCH_PAIR *pMatchPair = new MATCH_PAIR[T1_Keypoints->total];
 int descriptor_size = params.extended? 128 : 64;
 int nMatchingCount = FindMatchingPoints(T1_Keypoints, T1_Descriptors, T2_Keypoints, T2_Descriptors, descriptor_size, pMatchPair);
 printf("matching count = %d\n", nMatchingCount);

 CvPoint2D32f *pt1 = new CvPoint2D32f[nMatchingCount];
 CvPoint2D32f *pt2 = new CvPoint2D32f[nMatchingCount];

 int x1, y1, x2, y2;
 for(int k=0; k< nMatchingCount; k++)
 {
  //keypoint
  surf1 = (CvSURFPoint*) cvGetSeqElem(T1_Keypoints, pMatchPair[k].nA);
  x1 = cvRound(surf1->pt.x);
  y1 = cvRound(surf1->pt.y);

  surf2 = (CvSURFPoint*) cvGetSeqElem(T2_Keypoints, pMatchPair[k].nB);
  x2 = cvRound(surf2->pt.x) + T1Img->width;
  y2 = cvRound(surf2->pt.y);

  //line draw
  CvPoint r1 = cvPoint(x1, y1);
  CvPoint r2 = cvPoint(x2, y2);
  cvLine(MergeImg, r1, r2, CV_RGB(0, 0, 255));

  pt1[k] = surf1->pt;
  pt2[k] = surf2->pt;
 }

 //draw merged image
 cvNamedWindow("Merging Img",1);
 cvShowImage("Merging Img", MergeImg);
 ///////////////////////////////////////////////////////////////////////////////////////////


 
 ///////////////////////////////////////////////////////////////////////////////////////////
 //calculate homography
 CvPoint corners[4]={{0, 0}, {T1Img->width, 0}, {T1Img->width, T1Img->height}, {0, T1Img->height}};
 if(nMatchingCount< 4)
 {
  printf("We need more than 4 matching points");
  printf("to calculate a homography transform\n");
  return ;
 }

 CvMat M1, M2; 
 double H[9];
 CvMat mxH = cvMat(3, 3, CV_64F, H);
 M1 = cvMat(1, nMatchingCount, CV_32FC2, pt1);
 M2 = cvMat(1, nMatchingCount, CV_32FC2, pt2);
 if( !cvFindHomography(&M1, &M2, &mxH, CV_RANSAC, 2))
 {
  printf("Find Homography Fail!\n");
  return ;
 }
 
 //display homography
 printf(" Homography matrix\n");
 for( int rows=0; rows< 3; rows++ )
 {
  for( int cols=0; cols< 3; cols++ )
  {
   printf("%lf ", cvmGet(&mxH, rows, cols) );
  }
  printf("\n");
 }
 ///////////////////////////////////////////////////////////////////////////////////////////


 ///////////////////////////////////////////////////////////////////////////////////////////
 //make stitching image
 IplImage* WarpImg = cvCreateImage(cvSize(T1Img->width*2, T1Img->height*2), T1Img->depth, T1Img->nChannels); 
 cvWarpPerspective(T1Img, WarpImg, &mxH);
 cvSetImageROI(WarpImg, cvRect(0, 0, T2Img->width, T2Img->height));
 cvCopy(T2Img, WarpImg);
 cvResetImageROI(WarpImg);
 
 //draw stiching image
 cvNamedWindow("WarpImg Img",1);
 cvShowImage("WarpImg Img", WarpImg);
 /////////////////////////////////////////////////////////////////////////////////////////// 
 cvWaitKey(0);

 delete pMatchPair;
 delete pt1;
 delete pt2;


 cvReleaseImage(&WarpImg);

 cvReleaseImage(&T1Img);
 cvReleaseImage(&T2Img);

 cvReleaseImage(&mT1Img);
 cvReleaseImage(&mT2Img);

 cvReleaseImage(&MergeImg);

}


void MergeImages(IplImage* Image1, IplImage* Image2, IplImage* dstImage)
{
 cvSet(dstImage, CV_RGB(255, 255, 255));
 cvSetImageROI(dstImage, cvRect(0, 0, Image1->width, Image1->height));
 cvSetImageCOI(dstImage, 1); //채널 1
 cvCopy(Image1, dstImage); 
 cvSetImageCOI(dstImage, 2); //채널 2
 cvCopy(Image1, dstImage); 
 cvSetImageCOI(dstImage, 3); //채널 3
 cvCopy(Image1, dstImage);

 
 cvSetImageROI(dstImage, cvRect(Image1->width, 0, Image2->width, Image2->height));
 cvSetImageCOI(dstImage, 1); //채널 1
 cvCopy(Image2, dstImage);
 cvSetImageCOI(dstImage, 2); //채널 2
 cvCopy(Image2, dstImage);
 cvSetImageCOI(dstImage, 3); //채널 3
 cvCopy(Image2, dstImage);
 cvResetImageROI(dstImage);
 
}


int FindMatchingPoints(const CvSeq* tKeypoints, const CvSeq* tDescriptors, const CvSeq* srcKeypoints, const CvSeq* srcDescriptors, int descriptor_size, MATCH_PAIR *pMatchPair)
{
 int i;
 float* pA;
 int nMatchB;
 CvSURFPoint* surfA;
 int k=0;
 for(i=0; i< tDescriptors->total; i++)
 {
  pA = (float*) cvGetSeqElem(tDescriptors, i);
  surfA = (CvSURFPoint*) cvGetSeqElem(tKeypoints, i);
  nMatchB = FindNearestPoints(pA, surfA->laplacian, srcKeypoints, srcDescriptors, descriptor_size);
  if(nMatchB > 0)
  {
   pMatchPair[k].nA=i;
   pMatchPair[k].nB = nMatchB;
   k++;
  }
 }

 return k;
}


int FindNearestPoints(const float* pA, int laplacian, const CvSeq* srcKeypoints, const CvSeq* srcDescriptors, int descriptor_size)
{
 int i, k;
 float* pB;
 CvSURFPoint *surfB;
 int nMatch = -1;
 double sum2, min1 = 10000, min2 = 10000;
 for(i=0; i< srcDescriptors->total; i++)
 {
  surfB = (CvSURFPoint*) cvGetSeqElem(srcKeypoints, i);
  pB = (float*) cvGetSeqElem(srcDescriptors, i);
  if(laplacian != surfB->laplacian)
   continue;

  sum2 = 0.0f;
  for(k=0; k< descriptor_size; k++) { sum2 +=(pA[k]-pB[k])*(pA[k]-pB[k]); }

  if(sum2 <  min1)
  {
   min2 = min1;
   min1 = sum2;
   nMatch = i;
  }
  else if(sum2< min2) { min2 = sum2; }
 }
 if(min1< 0.6*min2)
  return nMatch;

 return -1;
}





Split color channels -> RGB, HSI, YCbCr, YUV, YIQ, YUW / C++ source / 칼라 채널 분리

Created Date : 2007.8
Language : C/C++
Tool : Microsoft Visual C++ 6.0 (MFC)
Library & Utilized : -
Reference : Simplified approach to image processing book -Randy Crane-
etc. : Bmp Image File
                                            RGB                                                   YCbCr


 
                                            YIQ                                                      YUV

                                             HSI                                                       YUW    

This program splits the channel into several version.
There are many color channels for image processing such as RGB, HSI, YCbCr, YUV, YIQ, YUW.
Each channels is made by specific formula that is introduced from many image processing books. The method of covert is simple and not difficult.

For example YCbCr is made by blow formula.
Y = 0.299*R + 0.587*G + 0.114*B
Cb = -0.16874*R + -0.33126*G + 0.5*B
Cr = 0.5*R + -0.41869*G - 0.08131*B

You can download entire source code and report document(doc) but the report is written by korean (sorry). -> < here >

If you have any question or opinion for improving, please reply.
Thank you.

(Please understand my bad english ability. If you point out my mistake, I would correct pleasurably. Thank you!!)
-------------------------------------

이 프로그램은 bmp파일을 열어서 여러가지 채널로 분리하는 간단한 영상 처리 프로그램입니다.
색 채널 분리는 이미지 처리 책에서 쉽게 그 방법과 원리를 찾아 볼 수 있습니다.
예를 들어 RGB에서 YCbCr로 분리하는 방법은 아래 수식으로 가능합니다.

Y = 0.299*R + 0.587*G + 0.114*B
Cb = -0.16874*R + -0.33126*G + 0.5*B
Cr = 0.5*R + -0.41869*G - 0.08131*B


더 자세한 내용은 링크한 저의 전체 소스 코드를 첨부하세요.
압축 파일에는 한글로 된 보고서도 포함되어 있습니다. - > < here >

오래 전에 만든 소스라 부족함이 많을 것 같네요.
문제점이나 개선 사항 있으면 답변 주세요.
감사합니다.