Zoeken…


Opmerkingen

Let op het type cv::Mat u te maken heeft. Als u bijvoorbeeld een cv::Mat van het type CV_8UC3 , maar deze image.at<uchar>(r,c) met image.at<uchar>(r,c) zal er geen fout optreden, maar uw programma zal onverwacht gedrag vertonen.

Toegang tot individuele pixelwaarden met cv :: Mat :: at ()

Om toegang te krijgen tot pixelwaarden in een OpenCV cv::Mat object, moet u eerst het type van uw matrix weten.

De meest voorkomende soorten zijn:

  • CV_8UC1 voor 8-bit 1-kanaals grijswaardenafbeeldingen;
  • CV_32FC1 voor 32-bit drijvende-komma 1-kanaals grijswaardenafbeeldingen;
  • CV_8UC3 voor 8-bit 3-kanaals kleurenafbeeldingen; en
  • CV_32FC3 voor 32-bit drijvende-komma 3-kanaals kleurenafbeeldingen.

De standaardinstelling met cv::imread maakt een CV_8UC3 matrix.

Om toegang te krijgen tot individuele pixels, is de veiligste, hoewel niet de meest efficiënte, het gebruik van cv::Mat::at<T>(r,c) methode waarbij r de rij van de matrix is en c de kolom is . Het sjabloonargument hangt af van het type matrix.

Laten we zeggen dat je een cv::Mat image . Afhankelijk van het type zullen de toegangsmethode en het pixelkleurtype verschillen.

  • Voor CV_8UC1 : uchar pixelGrayValue = image.at<uchar>(r,c) .
  • Voor CV_8UC3 : cv::Vec3b pixelColor = image.at<cv::Vec3b>(r,c) . Het object cv::Vec3b vertegenwoordigt een triplet van uchar waarden (gehele getallen tussen 0 en 255).
  • Voor CV_32FC1 : float pixelGrayValue = image.at<float>(r,c) .
  • Voor CV_32FC3 : cv::Vec3f pixelColor = image.at<cv::Vec3f>(r,c) . De cv::Vec3f object vertegenwoordigt een triplet van float waarden.

Merk op dat OpenCV afbeeldingen in rij- hoofdvolgorde weergeeft, zoals bijvoorbeeld Matlab of als de conventie in Algebra. Als uw image.at<..>(y,x) dus (x,y) , hebt u toegang tot de pixel met image.at<..>(y,x) .

Als alternatief, at<> ook ondersteuning via een enkel cv::Point argument.
In dit geval gebeurt de toegang in kolom-major :

image.at<..>(cv::Point(x,y));

Bekijk de OpenCV-documentatie voor meer informatie over deze methode.

Efficiënte pixeltoegang met cv :: Mat :: ptr wijzer

Als efficiëntie belangrijk is, is een snelle manier om pixels in een cv::Mat object te herhalen, de ptr<T>(int r) -methode te gebruiken om een aanwijzer naar het begin van rij r (op 0 gebaseerde index) te verkrijgen.

Afhankelijk van het matrixtype heeft de aanwijzer een ander sjabloon.

  • Voor CV_8UC1 : uchar* ptr = image.ptr<uchar>(r);
  • Voor CV_8UC3 : cv::Vec3b* ptr = image.ptr<cv::Vec3b>(r);
  • Voor CV_32FC1 : float* ptr = image.ptr<float>(r);
  • Voor CV_32FC3 : cv::Vec3f* ptr = image.ptr<cv::Vec3f>(r);

Dit ptr object kan vervolgens worden gebruikt om toegang te krijgen tot de pixelwaarde op rij r en kolom c door ptr[c] aan te roepen.

Om dit te illustreren, is hier een voorbeeld waarin we een afbeelding van schijf laden en de blauwe en rode kanalen omkeren, die pixel voor pixel werken:

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

int main(int argc, char** argv) {
    cv::Mat image = cv::imread("image.jpg", CV_LOAD_IMAGE_COLOR);

    if(!image.data) {
        std::cout << "Error: the image wasn't correctly loaded." << std::endl;
        return -1;
    }

    // We iterate over all pixels of the image
    for(int r = 0; r < image.rows; r++) {
        // We obtain a pointer to the beginning of row r
        cv::Vec3b* ptr = image.ptr<cv::Vec3b>(r);

        for(int c = 0; c < image.cols; c++) {
            // We invert the blue and red values of the pixel
            ptr[c] = cv::Vec3b(ptr[c][2], ptr[c][1], ptr[c][0]);
        }
    }

    cv::imshow("Inverted Image", image);
    cv::waitKey();

    return 0;
}

Pixelwaarden van een grijze afbeelding instellen en ophalen in C ++

// PixelAccessTutorial.cpp : Defines the entry point for the console 
// Environment: Visual studio 2015, Windows 10
// Assumptions: Opecv is installed configured in the visual studio project
// Opencv version: OpenCV 3.1

#include "stdafx.h"
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<string>
#include<iostream>

int main()
{

    cv::Mat imgOriginal;        // input image
    cv::Mat imgGrayscale;        // grayscale of input image

    std::cout << "Please enter an image filename : ";
    std::string img_addr;
    std::cin >> img_addr;

    std::cout << "Searching for " + img_addr << std::endl;

    imgOriginal = cv::imread(img_addr);            // open image

        if (imgOriginal.empty()) {                                    // if unable to open image
            std::cout << "error: image not read from file\n\n";        // show error message on command line
            return(0);                                                // and exit program
        }

    cv::cvtColor(imgOriginal, imgGrayscale, CV_BGR2GRAY);        // convert to grayscale

    const int channels = imgGrayscale.channels();
    printf("Number of channels = %d", channels);

    cv::Mat output ;
    imgGrayscale.copyTo(output); // Just to make sure the Mat objects are of the same size. 

    //Set the threshhold to your desired value
    uchar threshhold = 127; 

    if (channels == 1)
    {
        for (int x = 0; x<imgGrayscale.rows; x++) {
            for (int y = 0; y<imgGrayscale.cols; y++) {
                // Accesssing values of each pixel
                if (imgGrayscale.at<uchar>(x, y) >= threshhold) {
                    // Setting the pixel values to 255 if it's above the threshold
                    output.at<uchar>(x, y) = 254;
                }
                else if (imgGrayscale.at<uchar>(x, y) < threshhold) {
                    // Setting the pixel values to 255 if it's below the threshold
                    output.at<uchar>(x, y) = 0;
                }
                else {
                    // Just in case
                    printf("The value at (%d, %d) are not right. Value: %d\n", x, y, imgGrayscale.at<uchar>(x, y));
                }
            }
        }
    }
    else if (channels == 3)
    {
        // This is only for  gray scale images
        printf("\tThe image has 3 channels. The function does not support images with 3 channels.\n");
    }

    //Create windows to show image
    cv::namedWindow("Gray scale", CV_WINDOW_AUTOSIZE);    
    cv::namedWindow("Binary", CV_WINDOW_AUTOSIZE);        

    cv::imshow("Gray scale", imgGrayscale);        
    cv::imshow("Binary", output);

    cv::waitKey(0);                    // hold windows open until user presses a key

    return 0;
}

Alternatieve pixeltoegang met Matiterator

Het is niet de beste manier om door de pixels te bladeren; het is echter beter dan cv :: Mat :: op <T>.

Laten we aannemen dat u een kleurenafbeelding in uw map hebt en dat u elke pixel van deze afbeelding wilt herhalen en groene en rode kanalen wilt wissen (dit is een voorbeeld, u kunt dit op meer geoptimaliseerde manieren doen);

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp> 


int main(int argc, char **argv)
{

// Create a container
cv::Mat im; 

//Create a vector
cv::Vec3b *vec;

// Create an mat iterator
cv::MatIterator_<cv::Vec3b> it;

// Read the image in color format
im = cv::imread("orig1.jpg", 1);

// iterate through each pixel
for(it = im.begin<cv::Vec3b>(); it != im.end<cv::Vec3b>(); ++it)
{
    // Erase the green and red channels 
    (*it)[1] = 0;
    (*it)[2] = 0;
}


// Create a new window
cv::namedWindow("Resulting Image");

// Show the image
cv::imshow("Resulting Image", im);

// Wait for a key
cv::waitKey(0);

return 0;
}

Om dit te compileren met Cmake:

cmake_minimum_required(VERSION 2.8)
project(Main)
find_package(OpenCV REQUIRED)
add_executable(Main main.cpp)
target_link_libraries(Main ${OpenCV_LIBS})

De originele afbeelding: voer hier de afbeeldingsbeschrijving in

De verwerkte afbeelding: voer hier de afbeeldingsbeschrijving in

Merk op dat we niet alleen het blauwe kanaal aanraken.

Voor meer informatie: http://docs.opencv.org/2.4/opencv_tutorials.pdf Pagina: 145

Pixeltoegang in Mat

Individuele pixeltoegang in OpenCV Mat-structuur kan op meerdere manieren worden bereikt. Om te begrijpen hoe toegang te krijgen, is het beter om eerst de gegevenstypen te leren.

Basic Structures verklaart de basis datatypes. Kort CV_<bit-depth>{U|S|F}C(<number_of_channels>) is CV_<bit-depth>{U|S|F}C(<number_of_channels>) de basisstructuur van een type. Daarnaast is het belangrijk om Vec structuren te begrijpen.

typedef Vec<type, channels> Vec< channels>< one char for the type>

waarbij type een is van uchar, short, int, float, double en de tekens voor elk type respectievelijk b, s, i, f, d zijn.

Vec2b geeft bijvoorbeeld een unsigned char vector of 2 channels .

Beschouw Mat mat(R,C,T) waarbij R # rijen is, C # cols is en T type is. Enkele voorbeelden voor toegang tot de (i, j) coördinaat van mat zijn:

2D:

If the type is CV_8U or CV_8UC1 ---- //they are alias
mat.at<uchar>(i,j) // --> This will give char value of index (i,j)
//If you want to obtain int value of it
(int)mat.at<uchar>(i,j)

If the type is CV_32F or CV_32FC1 ---- //they are alias
mat.at<float>(i,j) // --> This will give float value of index (i,j)

3D:

If the type is CV_8UC2 or CV_8UC3 or more channels
mat.at<Vec2b/Vec3b>(i,j)[k] // note that (k < #channels)
//If you want to obtain int value of it
(int)mat.at<uchar>(i,j)[k] 

If the type is CV_64FC2 or CV_64FC3 
mat.at<Vec2d/Vec3d>(i,j)[k] // note that k < #channels

Houd er rekening mee dat het zeer cruciaal is om het juiste type in <...> , anders kunt u een runtime-fout of ongewenste resultaten hebben.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow