본문 바로가기

Project/증강현실을 이용한 사천성

영상처리를 이용한 붉은색 검출



우선 붉은 색 검출에 성공을 하긴 했는데
속도가 느리다.
한눈에 '느리다' 라는 느낌이 든다.

OnPaint 함수를 사용해서 OpenCV관련 처리들을 해주는데,
OnPaint함수 특성상 계~속 호출이 되기 때문에 발생하는 현상같다.

이제 코드를 모두 Thread화 시키는 작업을 하고, 색 추적 구현을 해야겠다.

void CameraManager::FindRedColor (CDC** pDC_YCbCr, CStatic *yCbCrCam)
{
	CRect	rect;
	int x, y;

	this->camera.Create_ipl_YCbCr_Image();
	this->camera.Create_ipl_bin_Image();
	this->camera.Create_RGB_Image();
	this->camera.Create_Y_Image();
	this->camera.Create_Cb_Image();
	this->camera.Create_Cr_Image();
	this->camera.Create_ipl_gray_Image();

	*pDC_YCbCr = yCbCrCam->GetDC();
	yCbCrCam->GetClientRect(&rect);
	x = rect.top;
	y = rect.left;
	rect.SetRect(x, y, x + CAM_WIDTH, y + CAM_HEIGHT);
	
	//RGB -> YCbCr로 변환
	cvCvtColor(this->camera.Get_ipl_OriginalImage(), this->camera.Get_ipl_YCbCr_Image(), CV_RGB2YCrCb);

	//YCbCr 3개의 채널을 각 각 채널로 분리
	cvCvtPixToPlane(this->camera.Get_ipl_YCbCr_Image(), this->camera.Get_Y_Image(),
		this->camera.Get_Cr_Image(), this->camera.Get_Cb_Image(), 0);

	ChangeRedColor ();
	AddEffect ();

	// 이진화 Image View
	this->camera.Get_cvv_bin_Image().CopyOf ( this->camera.Get_ipl_gray_Image() );
	this->camera.Get_cvv_bin_Image().DrawToHDC( (*pDC_YCbCr)->m_hDC, rect );

	//이미지 해제
	this->camera.Release_ipl_YCbCr_Image();
	this->camera.Release_Y_Image();
	this->camera.Release_Cb_Image();
	this->camera.Release_Cr_Image();
	this->camera.Release_RGB_Image();
	this->camera.Release_ipl_gray_Image();
	this->camera.Release_ipl_bin_Image();
}

void CameraManager::ChangeRedColor ()
{
	unsigned char temp_Y = 0;
	unsigned char temp_Cb = 0;
	unsigned char temp_Cr = 0;

	for(int i = 0 ; i < (this->camera.Get_ipl_YCbCr_Image())->height ; i++)
	{
		for(int j = 0 ; j < this->camera.Get_ipl_YCbCr_Image()->width ; j++)
		{
			temp_Cr = this->camera.Get_Cr_Image()->imageData[i * this->camera.Get_Cr_Image()->widthStep + j];
			temp_Cb = this->camera.Get_Cb_Image()->imageData[i * this->camera.Get_Cb_Image()->widthStep + j];

			// 붉은색이 있으면 흰색,아니면 검은색으로
			if( (MIN_RED_CR < temp_Cr) && (temp_Cr < MAX_RED_CR) )
			{
				if( (MIN_RED_CB < temp_Cb) && (temp_Cb < MAX_RED_CB) )
				{
					//검출 영역이면 흰색
					this->camera.Get_ipl_bin_Image()->
						imageData[i * this->camera.Get_ipl_bin_Image()->widthStep + j * 3 + 0] = WHITE;
					this->camera.Get_ipl_bin_Image()->
						imageData[i * this->camera.Get_ipl_bin_Image()->widthStep + j * 3 + 1] = WHITE;
					this->camera.Get_ipl_bin_Image()->
						imageData[i * this->camera.Get_ipl_bin_Image()->widthStep + j * 3 + 2] = WHITE;
				}
				else
				{
					//검출 영역이 아니면 0
					this->camera.Get_ipl_bin_Image()->
						imageData[i * this->camera.Get_ipl_bin_Image()->widthStep + j * 3 + 0] = BLACK;
					this->camera.Get_ipl_bin_Image()->
						imageData[i * this->camera.Get_ipl_bin_Image()->widthStep + j * 3 + 1] = BLACK;
					this->camera.Get_ipl_bin_Image()->
						imageData[i * this->camera.Get_ipl_bin_Image()->widthStep + j * 3 + 2] = BLACK;
				}
			}
			else
			{
				//검출 영역이 아니면 0
				this->camera.Get_ipl_bin_Image()->
					imageData[i * this->camera.Get_ipl_bin_Image()->widthStep + j * 3 + 0] = BLACK;
				this->camera.Get_ipl_bin_Image()->
					imageData[i * this->camera.Get_ipl_bin_Image()->widthStep + j * 3 + 1] = BLACK;
				this->camera.Get_ipl_bin_Image()->
					imageData[i * this->camera.Get_ipl_bin_Image()->widthStep + j * 3 + 2] = BLACK;
			}
		}
	}
}

void CameraManager::AddEffect ()
{
	// 구조화 요소 Create
	IplConvKernel *element = cvCreateStructuringElementEx(2, 2, 1, 1, CV_SHAPE_ELLIPSE, NULL);

	// 닫힘 연산
	cvDilate(this->camera.Get_ipl_bin_Image(), this->camera.Get_ipl_bin_Image(), element, 1); // 팽창 (배경을 축소시키고 객체의 크기를 확장)
	cvErode(this->camera.Get_ipl_bin_Image(), this->camera.Get_ipl_bin_Image(), element, 2); // 침식 (배경을 확장시키고 객체의 크기를 축소)
	cvDilate(this->camera.Get_ipl_bin_Image(), this->camera.Get_ipl_bin_Image(), element, 1); // 팽창

	cvMorphologyEx(this->camera.Get_ipl_bin_Image(), this->camera.Get_ipl_bin_Image(),
		this->camera.Get_ipl_YCbCr_Image(), element, CV_MOP_OPEN, 5);
	cvSmooth(this->camera.Get_ipl_bin_Image(), this->camera.Get_ipl_bin_Image(), CV_MEDIAN, 3, 1);
	cvSmooth(this->camera.Get_ipl_bin_Image(), this->camera.Get_ipl_bin_Image(), CV_GAUSSIAN, 3, 1);

	cvCvtColor(this->camera.Get_ipl_bin_Image(), this->camera.Get_RGB_Image(), CV_YCrCb2BGR); // YCrCb -> RGB
	cvCvtColor(this->camera.Get_RGB_Image(), this->camera.Get_ipl_gray_Image(), CV_RGB2GRAY); // RGB -> Gray
	
	// 이진화
	cvThreshold(this->camera.Get_ipl_gray_Image(), this->camera.Get_ipl_gray_Image(),
		THRESHOLD, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

	cvReleaseStructuringElement(&element); // 구조화 요소 Release
}

'Project > 증강현실을 이용한 사천성' 카테고리의 다른 글

빨강 추적  (1) 2010.02.19
영상 속도가 느린 이유  (0) 2010.02.18
AR을 이용한 사천성 알 출력  (0) 2010.02.17
RGB->YCbCr->이진화  (2) 2010.02.15
OpenCV로 영상 출력 성공, 하지만..  (0) 2010.02.10