uchar* _img_data,cv::resize;指针实现
时间: 2024-09-18 09:07:16 浏览: 42
要通过指针`uchar*`访问图像数据并执行`cv::resize`操作,你可以先使用`ptr()`函数从`cv::Mat`对象中获取指向像素数据的指针,然后按照图像数据的布局进行操作。这里以单通道灰度图像为例:
1. 获取原始图像数据的uchar指针[^1]:
```cpp
cv::Mat img = cv::Mat::eye(3, 3, CV_8UC1);
uchar* _img_data = img.ptr<uchar>(0); // 获取第0行(假设为第一行)的uchar数组指针
```
2. 使用`cv::resize`函数时,通常会创建一个新的`cv::Mat`来存储调整后的图像。由于它不会直接修改原图像,因此我们需要创建一个临时变量来保存新的数据。注意,`cv::resize`可能返回一个新的`cv::Mat`实例:
```cpp
cv::Size newSize(4, 4); // 新的尺寸
cv::Mat resized_img;
cv::resize(img, resized_img, newSize); // 对原图像进行缩放
// 注意:resized_img现在包含了新数据,但原图img保持不变
uchar* resized_data = resized_img.ptr<uchar>(0); // 获取新图像的第一行数据
```
相关问题
int m_nHeight = 4352, m_nWidth = 4352, m_nCutCols = 25, m_nCutRows = 25; uchar *m_pDefectMap = new uchar[m_nHeight * m_nWidth]; memset(m_pDefectMap, m_nHeight * m_nWidth * sizeof(uchar)); cv::Mat labels, centroids, stats; cv::Mat matDefectMap = cv::Mat(m_nHeight, m_nWidth, CV_8UC1, m_pDefectMap); cv::Mat roi = matDefectMap(cv::Rect(m_nCutCols, m_nCutRows, m_nWidth - 2 * m_nCutCols, m_nHeight - 2 * m_nCutRows)); cv::Mat dst = cv::Mat(cv::Size(roi.cols + 2, roi.rows + 2), CV_8UC1, cv::Scalar(0)); cv::copyMakeBorder(roi, dst, 1, 1, 1, 1, cv::BORDER_REFLECT_101);填充类型无效
根据您提供的代码,我注意到您在使用cv::copyMakeBorder函数时设置了填充类型为cv::BORDER_REFLECT_101,但您认为填充类型无效。
可能的原因是,您传递给cv::copyMakeBorder函数的输入图像roi的数据类型是CV_8UC1,即单通道8位无符号整数图像。然而,根据您的代码,您创建的输出图像dst的数据类型也是CV_8UC1。这意味着您尝试将单通道图像roi复制到单通道图像dst中,因此无论您设置任何填充类型,结果都将是相同的。
要解决这个问题,您可以尝试创建一个多通道图像作为输出图像dst,以便能够正确应用填充类型。例如,您可以使用以下代码创建一个三通道图像:
```cpp
cv::Mat dst = cv::Mat(cv::Size(roi.cols + 2, roi.rows + 2), CV_8UC3, cv::Scalar(0));
```
然后,您可以使用cv::copyMakeBorder函数将单通道图像roi复制到三通道图像dst中,并指定所需的填充类型。
希望这可以解决您的问题!如果还有其他疑问,请随时提问。
for(int i = 0; i < heatmaps.size[1] - 1; i ++) // resize cost 29 ms { cv::Mat heatMap(heatmaps.size[2], heatmaps.size[3], CV_32F, reinterpret_cast<float*>(const_cast<uchar*>(heatmaps.ptr(0, i)))); // heatMap.data = heatmaps.ptr(0, i); if (this->upsample_ratio != 1) { // cv::resize(heatMap, heatMap, cv::Size(0, 0), this->upsample_ratio, this->upsample_ratio, cv::INTER_CUBIC); // cv::resize(heatMap, heatMap, cv::Size(0, 0), this->upsample_ratio, this->upsample_ratio, cv::INTER_AREA); cv::resize(heatMap, heatMap, cv::Size(0, 0), this->upsample_ratio, this->upsample_ratio, cv::INTER_LINEAR); } heatmaps_channels[i] = heatMap; } 这段C++代码的详细解释
这段C++代码是一个for循环,用于对一个名为`heatmaps`的多维数组进行处理。下面是代码的详细解释:
1. `for(int i = 0; i < heatmaps.size[1] - 1; i++)`: 这是一个循环,从0开始迭代到`heatmaps`数组的第一维度大小减1。`heatmaps.size[1]`表示数组的第一维度大小。
2. `cv::Mat heatMap(heatmaps.size[2], heatmaps.size[3], CV_32F, reinterpret_cast<float*>(const_cast<uchar*>(heatmaps.ptr(0, i))));`: 这行代码定义了一个名为`heatMap`的`cv::Mat`对象。它使用了`heatmaps`数组中的数据来初始化,具体是通过`heatmaps.ptr(0, i)`获取指向数组中特定位置的指针,然后使用`reinterpret_cast<float*>`将指针转换为`float*`类型,最后通过`cv::Mat`构造函数创建一个`CV_32F`类型的矩阵。
3. `if (this->upsample_ratio != 1)`: 这是一个条件判断语句,检查变量`this->upsample_ratio`是否不等于1。
4. `cv::resize(heatMap, heatMap, cv::Size(0, 0), this->upsample_ratio, this->upsample_ratio, cv::INTER_LINEAR);`: 这行代码使用了OpenCV的resize函数对矩阵`heatMap`进行调整大小操作。调整大小的目标大小由`cv::Size(0, 0)`表示,表示将根据输入的`this->upsample_ratio`参数对图像进行放大或缩小。`cv::INTER_LINEAR`是插值方法,表示使用线性插值算法进行调整大小操作。
5. `heatmaps_channels[i] = heatMap;`: 这行代码将处理后的矩阵`heatMap`赋值给名为`heatmaps_channels`的数组的第`i`个元素。
这段代码的作用是遍历`heatmaps`数组的第一维度,并对每个元素进行调整大小操作,然后将调整后的结果存储在名为`heatmaps_channels`的数组中。
阅读全文