Мне вполне комфортно с OpenCV в Python. Я недавно перешел на версию C ++, и у меня продолжают возникать проблемы с cv::Mat
индексация, так как я слишком привык numpy
массивы.
В частности, я пытаюсь выяснить, есть ли лучший способ действовать в ограниченной области массива, не повторяя ее.
Например, допустим, у меня есть 10x15
унитарная матрица, и я хотел бы положить все, кроме последней строки, в ноль (или в другое случайное число); в Python я бы сделал что-то вроде этого:
import numpy as np
a = np.ones([10,15])
a[:-1,:-1] = 0
Как я могу добиться этого в C ++, определив cv::Mat a = cv::Mat::ones(10, 15, CV_32FC1);
?
Наилучшим способом, вероятно, является использование областей интереса. Cv mat может быть легко разбит с помощью прямоугольника следующим образом:
using namespace cv;
Mat a = Mat::ones(10, 15, CV_32FC1);
Rect rect(2, 2, 4, 4);
Mat roi = a(rect);
Вы можете в дальнейшем изменить roi
любым способом, который вам нравится, положите обратно в a
от:
roi.copyTo(a(rect));
Вы можете элегантно использовать новый Rect
в предыдущей строке, если его ширина и высота такие же, как у оригинала Rect
, Чтобы решить конкретный вопрос, проще всего создать новую матрицу со всеми нулями, а затем использовать copyTo с этим.
Я не знаю, является ли это наиболее эффективным способом сделать это, и если это не так, то кто-то исправит меня.
Одним из способов было бы установить значение изображения строка за строкой
for (int i = 0; i < image.rows-1; ++i)
{
image.row(i).setTo(Scalar(0,0,0));
}
Или, если указатель данных изображения продолжается, используйте std::fill
if(image.isContinuous())
std::fill_n(image.data, (image.rows-1) * image.cols * image.elemSize(), 0);