You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

cv::Mat转std::vector<double>数值异常及代码报错问题求助

Why Your OpenCV Mat → std::vector Conversion Is Failing (And How to Fix It)

Let's break down the two separate issues you're hitting, then walk through the fixes step by step:

1. Why You're Getting Tiny (~1e-180) Values

When you convert your image to grayscale with cvtColor(img, img, COLOR_RGB2GRAY), the resulting cv::Mat stores pixel data as 8-bit unsigned integers (CV_8U)—values from 0 to 255, not double.

Your first conversion code:

std::vector<double> imgvec; 
imgvec.assign(img.begin<double>(), img.end<double>());

forces OpenCV to interpret 8-bit byte data as 64-bit double values. This type mismatch reads the tiny 8-bit pixel patterns as full 64-bit doubles, which results in nonsensical, extremely small numbers.

2. Why the Second Code Snippet Throws a Compile Error

The shared code has two critical mistakes:

  • You're trying to fetch a double* pointer from a CV_8U Mat—this is a type mismatch, since the underlying data is uchar, not double.
  • The insert call is malformed: you only pass an end pointer (img.ptr<double>(i) + img.cols), but insert requires a full range (start and end pointers/iterators).

The Correct Conversion Approach

Since your grayscale image is CV_8U, you need to explicitly convert each 8-bit pixel to a double during the transfer. Here's the fixed code, handling both continuous and non-continuous Mats:

std::vector<double> imgvec;
imgvec.reserve(img.total()); // Preallocate space to avoid reallocations

if (img.isContinuous()) {
    // For continuous Mats, process the entire data block in one go
    const uchar* data = img.data;
    for (size_t i = 0; i < img.total(); ++i) {
        imgvec.push_back(static_cast<double>(data[i]));
    }
} else {
    // For non-continuous Mats, process each row individually
    for (int i = 0; i < img.rows; ++i) {
        const uchar* row_ptr = img.ptr<uchar>(i);
        for (int j = 0; j < img.cols; ++j) {
            imgvec.push_back(static_cast<double>(row_ptr[j]));
        }
    }
}

Alternative: Use OpenCV's Built-in Conversion

If you prefer a more concise, OpenCV-native approach, first convert the CV_8U Mat to a CV_64F (double-precision) Mat, then copy to the vector:

cv::Mat img_double;
img.convertTo(img_double, CV_64F); // Converts 0-255 uchar values to 0.0-255.0 doubles

std::vector<double> imgvec;
imgvec.assign(img_double.begin<double>(), img_double.end<double>());

This works because img_double now stores actual double values, so using begin<double>() and end<double>() is valid.

内容的提问来源于stack exchange,提问作者user7845839

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:43:39