簡體   English   中英

使用坐標Mat(OpenCV / C ++)訪問圖像值

[英]Access to image values using a Mat of coordinates (OpenCV/C++)

在openCV(C ++)中,我有一個圖像IMG ,我想在coor中的位置存儲中提取每個像素的值。 是否有可能以有效的方式獲得此像素值? foor循環(使用.at(i,j) )是否有效?是否有內置函數來執行此操作? 這是我的代碼:

cv::Mat IMG = cv::imread("image.png",CV_LOAD_IMAGE_GRAYSCALE);
cv::Mat coor = (cv::Mat_<float>(3,2) << 1, 0, 0, 1, 2, 2); // search coordinates
cv::Mat pixel_values;
// and I'd like to do something like this:
//This should result in a matrix with the same size as *coor*
pixel_values = IMG.at(coor); // similar to the matrix accesing method in Matlab. 

Threr是訪問cv :: Mat中“像素”值的不同方法。 您是否閱讀過OpenCV的文檔?

我建議你在這里開始表格

編輯我已經更正了代碼:此代碼適用於msvc 2015和opencv(3.1),但> 2也可以

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <cstdint>
using namespace std;

#if defined(NDEBUG)
#pragma comment(lib, "opencv_world310.lib")
#else
#pragma comment(lib, "opencv_world310d.lib")
#endif // 


cv::Mat GetPixelsFromMat( const cv::Mat& I, const std::vector<cv::Point2f>& points )
{
    // some pre-condition:
    cv::Mat res( 1, (int)points.size( ), CV_8UC1 );

    int i = 0;
    for( const auto& point : points )
        res.ptr( 0 )[ i++ ] = I.at<uchar>( cvRound( point.y ), cvRound( point.x ) );

    return res;
}

int main( int argc, char* argv[] )
{
    cv::Mat testImg( 1, 10, CV_8UC1 );
    for( int i = 0; i < 10; ++i )
        testImg.ptr( 0 )[ i ] = i;

    std::vector<cv::Point2f> points;
    points.push_back( cv::Point2f( 1, 0 ) );
    points.push_back( cv::Point2f( 5, 0 ) );
    points.push_back( cv::Point2f( 9, 0 ) );

    cv::Mat pixelsMap = GetPixelsFromMat( testImg, points );

    if( pixelsMap.ptr( 0 )[ 0 ] == 1 )
        cout << "OK 0" << endl;
    else
        cout << "FAIL 0" << endl;

    if( pixelsMap.ptr( 0 )[ 1 ] == 5 )
        cout << "OK 1" << endl;
    else
        cout << "FAIL 1" << endl;

    if( pixelsMap.ptr( 0 )[ 2 ] == 9 )
        cout << "OK 2" << endl;
    else
        cout << "FAIL 2";


    return EXIT_SUCCESS;
}

這是一個很大的簡化,但我認為這是一個起點。

如果您已經知道矩陣的類型,可以輕松使用@ elvis.dukaj 答案 您只需迭代坐標並檢索相應的像素值。

但是,如果你需要更通用的東西支持:

  • 任何類型和通道的輸入矩陣
  • 坐標的輸入列表是cv::Matstd::vector ,坐標為任何類型( intfloat等等)

你可能會發現這個getPixels函數很有用:

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;

Mat getPixels(InputArray _src, InputArray _coords)
{
    // Get src matrix
    Mat src = _src.getMat();

    // Get coords matrix, eventually convert to integer type
    Mat coords = _coords.getMat();
    if (coords.type() != CV_32S)
    {
        coords.convertTo(coords, CV_32S);
    }
    // Check coordinates
    int n = coords.checkVector(2, CV_32S);
    CV_Assert(n > 0);

    // Create output matrix
    Mat dst(n, 1, src.type());

    // Get pixel values at given coordinates
    int esz = src.elemSize();
    Point* coords_ptr = (Point*)coords.data;
    uchar* dst_ptr = dst.data;

    for (int i = 0; i < n; i++, dst_ptr += esz)
    {
        memcpy(dst_ptr, src.ptr(coords_ptr[i].y) + coords_ptr[i].x * esz, esz);
    }

    return dst;
}


int main() 
{

    Mat img(5, 5, CV_8UC1);
    randu(img, Scalar(0, 0, 0), Scalar(10, 10, 10));

    vector<Point> coor{ Point(1, 0), Point(0, 1), Point(2, 2) };
    //cv::Mat coor = (cv::Mat_<float>(3, 2) << 1, 0, 0, 1, 2, 2);

    Mat out = getPixels(img, coor);

    cout << out;

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM