Эффективный метод обхода изображений OpenCV

Указатель Обход

        Мат включает несколько видов имущества, строки являются количеством строк типа Мата, смещ_по_столбцы этого количества столбцов, каналы () представляет собой номер канала, то для каждой строки изображения, есть смещ_по_столбцам * () точка пикселя каналы, поэтому мы можем обход всех строк, для конкретной строки, а затем пересекая все пиксели, следующим образом:

int nl= image.rows; // 行数
// 每行的元素数量
int nc= image.cols * image.channels();
for (int j=0; j<nl; j++) {
    // 取得行 j 的地址
    uchar* data= image.ptr<uchar>(j);
    for (int i=0; i<nc; i++) {
        // 处理每个像素 ---------------------
        data[i]= 0;
        // 像素处理结束 ----------------
    } // 一行结束
}

PTR является свойство шаблона используется для получения адреса, и почему мы Yaoan пройти без линии траверс непосредственно из первого элемента в положении непосредственно п * пс это?

        Это происходит потому , цветное изображение, данные изображения буфера 3 байта перед значением верхнего левого пикселя трех каналов, следующие 3 байта второго пикселя первого ряда, и так далее (примечание OpenCV порядок канал по умолчанию BGR). Ширина W желаемого изображение высоты Н размера блока памяти Ш × × 3 uchars. Однако, из - за соображений производительности, мы будем использовать несколько дополнительных пикселей , чтобы заполнить длину строки. Это происходит потому, если число линий представляет собой число (например , 8) является целым кратным, производительность обработки изображений может быть улучшена, предпочтительно , чтобы выровнять данные в соответствии с конфигурацией памяти. Это не обязательно последний элемент позади каждой линии должен быть первым элементом следующей строки!

        Но мы можем использовать isContinuous (), чтобы проверить, есть заполняется, если не заполнено, isContinuous () возвращает истину, так что мы можем использовать следующий метод для траверсы:

int nl= image.rows; // 行数
// 每行的元素总数
int nc= image.cols * image.channels();
if (image.isContinuous()) {
// 没有填充的像素
     nc= nc*nl;
     nl= 1; // 它现在成了一个一维数组
}

for (int j=0; j<nl; j++) {
    uchar* data= image.ptr<uchar>(j);
    for (int i=0; i<nc; i++) {
        *data++ = 0;
    } // 一行结束
}

 

Во-вторых, перебирает

        Первое ввести экземпляр OpenCV резюме :: итератор Mat, вы должны сначала создать резюме :: объект MatIterator_. С резюме :: Mat_ Кроме того, это подчеркнул, что это шаблон подкласса. Поскольку изображения итераторы используются для доступа к элементу изображения, оно должно быть сделано четким типом возвращаемого значения во время компиляции. Он может быть определен итератор цветного изображения:

cv::MatIterator_<cv::Vec3b> it;


        Вы можете также использовать итератор типа в Mat_ определения класса шаблона:

cv::Mat_<cv::Vec3b>::iterator it;


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

 

        Например, код для цветного изображения на траверсу, как:

// 迭代器
cv::Mat_<cv::Vec3b>::iterator it= image.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::iterator itend= image.end<cv::Vec3b>();

// 扫描全部像素
for ( ; it!= itend; ++it) {
    //对像素点的处理
    (*it)[0] = 255;
    (*it)[1] = 255;
    (*it)[2] = 255;
}


 

 

 

发布了11 篇原创文章 · 获赞 14 · 访问量 1538

рекомендация

отblog.csdn.net/qq_41685265/article/details/104089725
рекомендация