1) 1차 DoG filter 만들기: x방향과 y방향의 local maxima를 찾는다.
swPark_2000rti.pdf 440쪽:
"To find the edge of the grid, a first-order Derivative of Gaussian
(DoG) filter with a kernel h = [-1, -7, -15, 0, 15, 7, 1] is used."
/* Test: feature point extraction in implementing virtual studio
: using Gaussin gradient filter, first-order Derivative of Gaussian (DoG) filter
with a kernel h = [-1, -7, -15, 0, 15, 7, 1]
ref. swPark_2000rti.pdf:440p
2010, lym
camera: Logitech QuickCam Pro 4000
*/
// + non maximum suppression
#include <OpenCV/OpenCV.h>
#include <iostream>s
using namespace std;
// non-maximum suppression (NMS)
void NonMaximumSuppression ( IplImage* image, int kernel, int threshold )
{
for ( int y = 0; y < image->height; y++ )
{
cout << "y = " << y << endl;
for ( int x = 0; x < image->width; x++ )
{
if( x == image->width - 1 ) {
x = x;
}
float intensity = CV_IMAGE_ELEM( image, float, y, x );
if ( intensity > threshold ) {
float neighbor;
int flag = 0;
for ( int ky = -kernel; ky <= kernel; ky++ ) // in y-direction
{
if ( y+ky < 0 || y+ky >= image->height ) { // border check
continue;
}
for ( int kx = -kernel; kx <= kernel; kx++ ) // in x-direction
{
if ( x+kx < 0 || x+kx >= image->width ) { // border check
continue;
}
neighbor = CV_IMAGE_ELEM( image, float, y+ky, x+kx );
if ( intensity < neighbor ) {
CV_IMAGE_ELEM( image, float, y, x ) = 0.0;
flag = 1;
break;
}
}
if ( 1 == flag ) {
break;
}
}
}
else {
CV_IMAGE_ELEM( image, float, y, x ) = 0.0;
}
}
}
}
int main()
{
IplImage* iplInput = 0; // input image
IplImage* iplGray = 0; // grey image converted from input image
IplImage *iplTemp = 0; // converted image from input image with a change of bit depth
// IplImage* iplDoG = 0; // filtered image by DoG
IplImage* iplDoGx = 0; // filtered image by DoG in x-direction
IplImage* iplDoGy = 0; // filtered image by DoG in y-direction
// initialize capture from a camera
CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0
int count = 0; // number of grabbed frames
while(1) {
// get video frames from the camera
if ( !cvGrabFrame(capture) ) {
printf("Could not grab a frame\n\7");
exit(0);
}
else {
cvGrabFrame( capture ); // capture a frame
iplInput = cvRetrieveFrame(capture); // retrieve the caputred frame
if(iplInput) {
if(0 == count) {
// create an image header and allocate the image data
/* iplGray = cvCreateImage(cvGetSize(iplInput), 8, 1);
iplDoGx = cvCreateImage(cvGetSize(iplInput), 8, 1);
iplDoGy = cvCreateImage(cvGetSize(iplInput), 8, 1);
*/
iplGray = cvCreateImage(cvGetSize(iplInput), 8, 1);
iplTemp = cvCreateImage(cvGetSize(iplInput), IPL_DEPTH_32F, 1);
iplDoGx = cvCreateImage(cvGetSize(iplInput), IPL_DEPTH_32F, 1);
iplDoGy = cvCreateImage(cvGetSize(iplInput), IPL_DEPTH_32F, 1);
}
// convert the input color image to gray one
cvCvtColor(iplInput, iplGray, CV_BGR2GRAY); // convert an image from one color space to another
// convert one array to another with optional linear transformation
cvConvert(iplGray, iplTemp);
// increase the frame number
count++;
}
cvShowImage( "input", iplInput );
// convolve an image with the kernel
// void cvFilter2D(const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchor=cvPoint(-1, -1)
cvFilter2D( iplTemp, iplDoGx, &DoGx ); // convolve an image with the DoG kernel in x-direction
cvFilter2D( iplTemp, iplDoGy, DoGy ); // convolve an image with the DoG kernel in y-direction
// ref. http://opencv.willowgarage.com/documentation/operations_on_arrays.html?highlight=cvabs#cvAbsDiffS
cvAbs(iplDoGx, iplDoGx);
cvAbs(iplDoGy, iplDoGy);
Try #1.
-1) 필터링의 결과 이미지의 bit depth를 "8"이 아니라 "IPL_DEPTH_32F"로 바꾼 다음, 음수로 나온 gradient 값을 양수로 바꾸어 준다.
그런데, 입력 영상을 담을 메모리를 별도로 생성하지 않고, 다음과 같이 비디오 프레임 캡처 시 만들어 주므로 인위적으로 설정해 줄 수 없다.
shift – Value added to the scaled source array elements
-2) Non Maximum Suppression (NMS)
이웃 화소들의 세기값을 비교하여 해당 픽셀이 최대값이 아니면 "0"으로 하여 지워 준다
/* Test: feature point extraction in implementing virtual studio
: using Gaussin gradient filter, first-order Derivative of Gaussian (DoG) filter
with a kernel h = [-1, -7, -15, 0, 15, 7, 1]
ref. swPark_2000rti.pdf:440p
2010, lym
camera: Logitech QuickCam Pro 4000
*/
#include <OpenCV/OpenCV.h>
#include <iostream>s
using namespace std;
// non-maximum suppression (NMS)
void NonMaximumSuppression ( IplImage* image, int kernel, int threshold )
{
for ( int y = 0; y < image->height; y++ )
{
cout << "y = " << y << endl;
for ( int x = 0; x < image->width; x++ )
{
if( x == image->width - 1 ) {
x = x;
}
float intensity = CV_IMAGE_ELEM( image, float, y, x );
if ( intensity > threshold ) {
float neighbor;
int flag = 0;
for ( int ky = -kernel; ky <= kernel; ky++ ) // in y-direction
{
if ( y+ky < 0 || y+ky >= image->height ) { // border check
continue;
}
for ( int kx = -kernel; kx <= kernel; kx++ ) // in x-direction
{
if ( x+kx < 0 || x+kx >= image->width ) { // border check
continue;
}
neighbor = CV_IMAGE_ELEM( image, float, y+ky, x+kx );
if ( intensity < neighbor ) {
CV_IMAGE_ELEM( image, float, y, x ) = 0.0;
flag = 1;
break;
}
}
if ( 1 == flag ) {
break;
}
}
}
else {
CV_IMAGE_ELEM( image, float, y, x ) = 0.0;
}
}
}
}
int main()
{
IplImage* iplInput = 0; // input image
IplImage* iplGray = 0; // grey image converted from input image
IplImage *iplTemp = 0; // converted image from input image with a change of bit depth
// IplImage* iplDoG = 0; // filtered image by DoG
IplImage* iplDoGx = 0; // filtered image by DoG in x-direction
IplImage* iplDoGy = 0; // filtered image by DoG in y-direction
// initialize capture from a camera
CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0
int count = 0; // number of grabbed frames
while(1) {
// get video frames from the camera
if ( !cvGrabFrame(capture) ) {
printf("Could not grab a frame\n\7");
exit(0);
}
else {
cvGrabFrame( capture ); // capture a frame
iplInput = cvRetrieveFrame(capture); // retrieve the caputred frame
if(iplInput) {
if(0 == count) {
// create an image header and allocate the image data
/* iplGray = cvCreateImage(cvGetSize(iplInput), 8, 1);
iplDoGx = cvCreateImage(cvGetSize(iplInput), 8, 1);
iplDoGy = cvCreateImage(cvGetSize(iplInput), 8, 1);
*/
iplGray = cvCreateImage(cvGetSize(iplInput), 8, 1);
iplTemp = cvCreateImage(cvGetSize(iplInput), IPL_DEPTH_32F, 1);
iplDoGx = cvCreateImage(cvGetSize(iplInput), IPL_DEPTH_32F, 1);
iplDoGy = cvCreateImage(cvGetSize(iplInput), IPL_DEPTH_32F, 1);
}
// convert the input color image to gray one
cvCvtColor(iplInput, iplGray, CV_BGR2GRAY); // convert an image from one color space to another
// convert one array to another with optional linear transformation
cvConvert(iplGray, iplTemp);
// increase the frame number
count++;
}
cvShowImage( "input", iplInput );
// convolve an image with the kernel
// void cvFilter2D(const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchor=cvPoint(-1, -1)
cvFilter2D( iplTemp, iplDoGx, &DoGx ); // convolve an image with the DoG kernel in x-direction
cvFilter2D( iplTemp, iplDoGy, DoGy ); // convolve an image with the DoG kernel in y-direction
// ref. http://opencv.willowgarage.com/documentation/operations_on_arrays.html?highlight=cvabs#cvAbsDiffS
cvAbs(iplDoGx, iplDoGx);
cvAbs(iplDoGy, iplDoGy);
/* Test: feature point extraction in implementing virtual studio
: using Gaussin gradient filter, first-order Derivative of Gaussian (DoG) filter
with a kernel h = [-1, -7, -15, 0, 15, 7, 1]
ref. swPark_2000rti.pdf:440p
camera: Logitech QuickCam Pro 4000
2010, lym & kyu
*/
// + non maximum suppression
#include <OpenCV/OpenCV.h>
#include <iostream>
using namespace std;
// non-maximum suppression (NMS)
void nonMaximumSuppression ( IplImage* image, int kernel, int threshold )
{
for ( int y = 0; y < image->height; y++ )
{
// cout << "y = " << y << endl;
for ( int x = 0; x < image->width; x++ )
{
float intensity = CV_IMAGE_ELEM( image, float, y, x );
if ( intensity > threshold ) {
float neighbor;
int flag = 0;
for ( int ky = -kernel; ky <= kernel; ky++ ) // in y-direction
{
if ( y+ky < 0 || y+ky >= image->height ) { // border check
continue;
}
for ( int kx = -kernel; kx <= kernel; kx++ ) // in x-direction
{
if ( x+kx < 0 || x+kx >= image->width ) { // border check
continue;
}
neighbor = CV_IMAGE_ELEM( image, float, y+ky, x+kx );
if ( intensity < neighbor ) {
CV_IMAGE_ELEM( image, float, y, x ) = 0.0;
flag = 1;
break;
}
}
if ( 1 == flag ) {
break;
}
}
}
else {
CV_IMAGE_ELEM( image, float, y, x ) = 0.0;
}
}
}
}
// non-maximum suppression (NMS)
void nonMaximumSuppression2 ( IplImage* image, IplImage* image2, int kernel)
{
float neighbor, neighbor2;
for ( int y = 0; y < image->height; y++ )
{
// cout << "y = " << y << endl;
for ( int x = 0; x < image->width; x++ )
{
float intensity = CV_IMAGE_ELEM( image, float, y, x );
// if ( intensity > threshold ) {
if (intensity > 0) {
int flag = 0;
for ( int ky = -kernel; ky <= kernel; ky++ ) // in y-direction
{
if ( y+ky < 0 || y+ky >= image->height ) { // border check
continue;
}
for ( int kx = -kernel; kx <= kernel; kx++ ) // in x-direction
{
if ( x+kx < 0 || x+kx >= image->width ) { // border check
continue;
}
neighbor = CV_IMAGE_ELEM( image, float, y+ky, x+kx );
neighbor2 = CV_IMAGE_ELEM( image2, float, y+ky, x+kx );
// if ( intensity < neighbor ) {
if ( intensity < neighbor || intensity < neighbor2) {
CV_IMAGE_ELEM( image, float, y, x ) = 0.0;
flag = 1;
break;
}
}
if ( 1 == flag ) {
break;
}
}
}
else {
CV_IMAGE_ELEM( image, float, y, x ) = 0.0;
}
}
}
}
// in the gradient direction
void selectEdges( IplImage* image1, IplImage* image2 )
{
for ( int y = 0; y < image1->height; y++ )
{
// cout << "y = " << y << endl;
for ( int x = 0; x < image1->width; x++ )
{
if( x == image1->width - 1 ) {
x = x;
}
float intensity1 = CV_IMAGE_ELEM( image1, float, y, x );
if ( intensity1 > 0.0 ) { // if the pixel is a edge point surviving NMS
float intensity2 = CV_IMAGE_ELEM( image2, float, y, x );
// compare it with the gradient value in the other direction
if ( intensity1 < intensity2 ) {
CV_IMAGE_ELEM( image1, float, y, x ) = 0.0;
}
}
}
}
}
int main()
{
IplImage* iplInput = 0; // input image
IplImage* iplGray = 0; // grey image converted from input image
IplImage *iplTemp = 0; // converted image from input image with a change of bit depth
// IplImage* iplDoG = 0; // filtered image by DoG
IplImage* iplDoGx = 0, *iplDoGxClone; // filtered image by DoG in x-direction
IplImage* iplDoGy = 0, *iplDoGyClone; // filtered image by DoG in y-direction
// initialize capture from a camera
CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0
int count = 0; // number of grabbed frames
while(1) {
// get video frames from the camera
// if (0) {
if ( !cvGrabFrame(capture) ) {
printf("Could not grab a frame\n\7");
exit(0);
}
else {
cvGrabFrame( capture ); // capture a frame
iplInput = cvRetrieveFrame(capture); // retrieve the caputred frame
// iplInput = cvLoadImage("P:/input.bmp"); // retrieve the caputred frame
}
// convert the input color image to gray one
cvCvtColor(iplInput, iplGray, CV_BGR2GRAY); // convert an image from one color space to another
// convert one array to another with optional linear transformation
cvConvert(iplGray, iplTemp);
// increase the frame number
count++;
}
cvShowImage( "input", iplInput );
// convolve an image with the kernel
// void cvFilter2D(const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchor=cvPoint(-1, -1)
cvFilter2D( iplTemp, iplDoGx, &DoGx ); // convolve an image with the DoG kernel in x-direction
cvFilter2D( iplTemp, iplDoGy, DoGy ); // convolve an image with the DoG kernel in y-direction
// ref. http://opencv.willowgarage.com/documentation/operations_on_arrays.html?highlight=cvabs#cvAbsDiffS
cvAbs(iplDoGx, iplDoGx); cvAbs(iplDoGy, iplDoGy);