2015-03-15 6 views
1

У меня есть функция, которая принимает изображение, преобразует его в HSV и устанавливает V в 100. Однако, похоже, также изменяется исходное изображение.OpenCV cvtColor тоже изменяет исходное изображение

Mat hsvfilter(const Mat& img) { 
    Mat result; 
    cvtColor(img, result, CV_BGR2HSV); 
    for (int j = 0; j < img.rows; j++) 
    for (int i = 0; i < img.cols; i++) 
     result.at<Vec3d>(i, j)[2] = 100; 
    return result; 
} 

Вот как я это называю:

Mat original = imread("pic.png"); 
Mat converted = hsvfilter(original); 

namedWindow("original", CV_WINDOW_AUTOSIZE); 
imshow("original", original); 

namedWindow("converted", CV_WINDOW_AUTOSIZE); 
imshow("converted", converted); 

waitKey(0); 

И исходное изображение и преобразованные изображения в конечном итоге, странные черные вертикальные полосы. Я считаю, что у моего кода есть некоторые проблемы с указателями или памятью, но я не могу понять, где. Любая помощь будет оценена по достоинству.

EDIT: ВОТ Фиксированный КОД

Mat hsvfilter(const Mat& img) { 
    Mat result; 
    cvtColor(img, result, CV_BGR2HSV); 
    for (int j = 0; j < result.rows; j++) { 
    for (int i = 0; i < result.cols; i++) { 
     result.at<cv::Vec3b>(j, i)[2] = 100; 
    } 
    } 
    return result; 
} 
+0

Для проверки работоспособности попробуйте проверить, сохраняется ли проблема, если вы выполняете 'Mat convert = hsvfilter (original.clone());'. При клонировании функция доступа к памяти «оригинала» не существует. – ChronoTrigger

ответ

1
  1. Ваша функция hsvFilter должна выглядеть следующим образом:

    Mat hsvfilter(const Mat& img) { 
    Mat result; 
    cvtColor(img, result, CV_BGR2HSV); 
    for (int j = 0; j < result.rows; j++) //you are modyfying "result" object, not img 
        for (int i = 0; i < result.cols; i++) //same as above 
         result.at<Vec3d>(j, i)[2] = 100; //OpenCV uses (y,x) indexing 
    return result; 
    } 
    

    В этой ситуации THER нет никакой разницы в использовании img.cols, img.rows/result.cols, result.rows, потому что размер обоих массивов (изображений) одинаковый, b ut вообще не забывайте об этом :) Второй комментарий больше не нуждается в объяснении.

  2. Как правило, код выглядит хорошо, на мой взгляд, он должен работать. Пробовали ли вы его протестировать без вызова функции hsvFilter (просто отобразите исходное изображение)?

  3. Если вы хотите сохранить созданные окна в течение некоторого времени, используйте этот код вместо waitKey(0);:

    while(waitKey(100) != 'q') 
    { 
        //all imshow calls 
    } 
    

Теперь, когда вы хотите выйти, просто нажмите «Q» (вы должны активируйте одно из ваших окон приложения).

+0

Проблема заключалась в том, что OpenCV использует (y, x) индексацию. Я, вероятно, получал доступ к матрице за пределами, и вместо того, чтобы C++ выдавал ошибку, она просто модифицировала память исходной матрицы. – BinRoot