Как сдвинуть элементы Cvmat в JavaCV

со временем пишу маленькое seam-carving-приложение

Моя проблема состоит в том, чтобы эффективно удалить обнаруженный «шов» с изображения.

У меня есть следующий код:

    private void removePathFromImageV(CvMat img, int[] path){

    int band = 3;

    double ch = 0.0;
        for (int y = 0; y < img.rows()-1; ++y){
            for (int x = path[y]-1; x < img.cols()-1; ++x){

                for (int b = 0; b < band; ++b){
                ch = img.get(y,x+1,b);
                img.put(y,x,b,ch);
            }
        }
    }

}

есть ли возможность сместить элементы из path[y]-1 в img.cols()-1?

Привет


person 501 - not implemented    schedule 16.10.2012    source источник
comment
не думай так. Вы обеспокоены эффективностью вашей фактической реализации?   -  person remi    schedule 17.10.2012
comment
да, мне нужно ускорение... со временем это решение становится медленным, и для решения этой функции для больших изображений требуется много времени.   -  person 501 - not implemented    schedule 17.10.2012
comment
Java очень медленный для такого рода операций. Я бы использовал JNI для ускорения.   -  person Tae-Sung Shin    schedule 17.10.2012


Ответы (1)


Ваша проблема заключается в том, что вы должны подавлять пиксели в разных местах для каждой строки, и наличие структуры изображения для этого неэффективно, поскольку вам нужно сместить все пиксели после удаленного пикселя. Вы можете попытаться преобразовать все изображение в структуру данных, которая будет эффективна для операций удаления, например. в C++, std::deque, двусторонняя очередь с итераторами произвольного доступа. Затем вы можете легко подавить элементы в каждой строке. В конце вы можете скопировать обратно из своей структуры в правильное изображение.

Вот идея, на С++

// assuming image is a CV_8UC3 image
std::deque<std::deque<cv::Vec3b> > pixelsDeq(image.rows, std::deque<cv::Vec3b>(image.cols));
for (int i = 0; i < image.rows; ++i)
  for (int j = 0; j < image.cols; ++j)
    pixelsDeq[i][j] = image.at<cv::Vec3b>(i, j);

// then remove pixels from the path (remove sequentially for all the paths you probably have)
  for (int j = 0; j < image.rows; ++j) {
    pixelsDeq[j].erase(pixelsDeq[j].begin() + paths[j]);


// at the end, copy back to a proper image
cv::Mat output = cv::Mat::zeros(pixelsDeq.size(), pixelsDeq[0].size(), CV_8UC3);
for (int i = 0; i < output.rows; ++i) {
  for (int j = 0; j < output.cols; ++j) {
    output.at<cv::Vec3b>(i,j) = pixelsDeq[i][j];
  } 
}
person remi    schedule 17.10.2012
comment
спасибо за фрагмент, это умственное упражнение. Я позабочусь о том, чтобы реализовать что-то подобное в java или jni. - person 501 - not implemented; 17.10.2012
comment
проверьте шаблонные контейнеры, реализующие интерфейс Collection в Java, вы можете сделать то же самое, но я плохо знаю Java - person remi; 18.10.2012