Перейти к содержимому
Compvision.ru
alexfriend

Работа со скалярами и матрицами

Recommended Posts

Добрый день.

Возник пару вопросов по OpenCV.

Реализую шоковый фильтр изображения, для вычисления производных необходимы некоторые арифметические преобразования над матрицами.

1. Подскажите, разумно ли использовать функции cvGet2D и cvSet2D для этого?

2. Никак не найду функции для работы со скалярами. К примеру, необходимо присвоить значения некоторым элементам в матрице изображения.

Приходится обращаться к полю val скаляра. Есть ли какие-либо заготовленные функции?

Покопавшись в коде самой библиотеки для работы со скаляром нашел разве что функцию cvRawDataToScalar

Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

1. Я в цикле прохожу по "сырым" данным изображения/матрицы. Или ищу в справке необходимые мне функции - очень часто всё уже реализовано. Какие производные тебе нужны?

2. Да, со скалярами через val работаю. А что не устраивает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

1. Ну в нужной мне реализации фильтра считается первая производная.


   I_mx = I-I(:,[1 1:nx-1]);

   I_px = I(:,[2:nx nx])-I;

   I_my = I-I([1 1:ny-1],;

   I_py = I([2:ny ny],-I;

   I_x = (I_mx+I_px)/2;


   ...


   a_grad_I = sqrt(Dx.^2+Dy.^2);

[/code]


 

Я попробовал оператор Собеля, но значения не совпали. 

Как именно лучше ходить по сырым изображениям? Через ptr, как на робофоруме писали?

[code] for( int y=0; y<image->height; y++ ) { uchar* ptr = (uchar*) (image->imageData + y * image->widthStep); for( int x=0; x<image->width; x++ ) { ptr[3*x] = 0; // B ptr[3*x+1] = 0; // G ptr[3*x+2] = 255; // R } }
2. Проблема оказалась не в скалярах. Указанные выше преобразования влекут появление отрицательных интенсивностей. Таким образом, мне надо передать в функцию изображение, вытащить из него сырую матрицу cvMat, а с ней уже делать то, что нужно. У нее, надеюсь, нету обнуления отрицательных значений val. Вопрос, как именно вытащить эту матрицу? Нашел такой пример, но не разобрался еще.

..

CvMat hdr;

CvMat *mass = cvReshape(image,&hdr,1);

..

Извиняюсь за наивные вопросы, с библиотекой еще не познакомился как надо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

1. Ну в нужной мне реализации фильтра считается первая производная.


   I_mx = I-I(:,[1 1:nx-1]);

   I_px = I(:,[2:nx nx])-I;

   I_my = I-I([1 1:ny-1],;

   I_py = I([2:ny ny],-I;

   I_x = (I_mx+I_px)/2;


   ...


   a_grad_I = sqrt(Dx.^2+Dy.^2);

[/code]


 

Я попробовал оператор Собеля, но значения не совпали. 

Как именно лучше ходить по сырым изображениям? Через ptr, как на робофоруме писали?

[code] for( int y=0; y<image->height; y++ ) { uchar* ptr = (uchar*) (image->imageData + y * image->widthStep); for( int x=0; x<image->width; x++ ) { ptr[3*x] = 0; // B ptr[3*x+1] = 0; // G ptr[3*x+2] = 255; // R } }
2. Проблема оказалась не в скалярах. Указанные выше преобразования влекут появление отрицательных интенсивностей. Таким образом, мне надо передать в функцию изображение, вытащить из него сырую матрицу cvMat, а с ней уже делать то, что нужно. У нее, надеюсь, нету обнуления отрицательных значений val. Вопрос, как именно вытащить эту матрицу? Нашел такой пример, но не разобрался еще.

..

CvMat hdr;

CvMat *mass = cvReshape(image,&hdr,1);

..

Извиняюсь за наивные вопросы, с библиотекой еще не познакомился как надо.
Вот:
CvMat *mat = cvCreateMat( img->height, img->width, CV_64FC3); // матрица с 3 каналами

cvConvert(img, mat);

Или так:

http://opencv.willowgarage.com/documentation/cpp/c++_cheatsheet.html

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Расчет производной по Вашей схеме (Для одноканального изображения):


// Вычисление градиентов по x и y
void gradient(IplImage* src, IplImage* dx, IplImage* dy)
{
int w=src->width;
int h=src->height;
int i1,i2;
int j1,j2;
double u00;
double u10;
double um10;
double u01;
double um01;
for(int i=0;i<w;i++)
{
i1=((i+1) >(w-1)) ? i-1 : i+1; // i+1
i2=((i-1) < 0 ) ? i+1 : i-1; // i-1
for(int j=0;j<h;j++)
{

u00=cvGetReal2D(src,j,i);
j1=((j+1) >(h-1)) ? j-1 : j+1; // j+1
j2=((j-1) <(0)) ? j+1 : j-1; // j-1
u10=cvGetReal2D(src,j,i1);
um10=cvGetReal2D(src,j,i2);
u01=cvGetReal2D(src,j1,i);
um01=cvGetReal2D(src,j2,i);
if(dx){cvSetReal2D(dx,j,i,(0.5*(u10-um10)));}
if(dy){cvSetReal2D(dy,j,i,(0.5*(u01-um01)));}
}
}
}
[/code]

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×