in time I'm writing a little seam-carving
-application
My problem is to remove the detected "seam" from the image in a efficient way.
I have the following code:
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);
}
}
}
}
is there a option to shift elements from path[y]-1 to img.cols()-1?
greetings
Your problem is that you must suppress pixels at different location for each row, and having an image structure to do that is not efficient, since you have to shift all the pixels after your deleted pixel. You can try to convert your whole image to a data structure that would be efficient for delete operations, e.g. in C++, std::deque
, a double-ended queue with random access iterators. Then you can easily suppress elements in each row. At the end, you can copy back from your structure to a proper image.
Here is the idea, in C++
// 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];
}
}