IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> opencv4.5.1 C++ 指针遍历操作像素图像出现周期性条纹的问题解决 -> 正文阅读

[人工智能]opencv4.5.1 C++ 指针遍历操作像素图像出现周期性条纹的问题解决

最近在使用opencv做一些大数据量且快速的图像计算,程序需要经常遍历像素,所以我捡起以前的知识直接用Mat.data这个成员来做指针的操作。有时候会比它重载的运算符计算速度要快一些,而且在一些地方用的挺顺利的,直到我的结果图像出现了意想不到的问题。

过程

1.选取ROI图像
2.对ROI图像使用at()方法进行遍历,结果图像正确。
2.对ROI图像取Mat.data 进行指针遍历,图像出现问题。

原因

自从工作以来,使用opencv我一直都是能用就算,以实践为主,很少去深入研究深层原理。在这里我个人认为问题原因在于:选取的ROI取指针指向的内存是原图的内存位置,或者说ROI图像就是使用了原图的内存,原图并没有消失。 Mat.at()方法可以正确操作是因为此方法是基于生成ROI的索引来操作的,所以能取到目标的像素,而指针操作不正确则是由于它遍历的范围是原图的 p 到 p + N(其中uchar* p = Mat.data,N为像素数,或者说偏移量)的像素范围,所以会发生一个周期性的条纹现象。

简单画了一下图,大概是这个样子的:
在这里插入图片描述
图片我后面才想起来加,没有特意去测试,相当于我上面文字的图像表示吧。

解决

把ROI图像克隆到一个新的矩阵里,对这个新的矩阵进行操作。

最后

欢迎指正。

测试代码

#include <iostream>
#include <opencv2/opencv.hpp>

#ifdef _DEBUG
#pragma comment(lib, "opencv_world451d.lib")
#else
#pragma comment(lib, "opencv_world451.lib")
#endif

using namespace std;
using namespace cv;


int main(int argc, char* argv[])
{
	Mat src = imread("bird.jpg", IMREAD_GRAYSCALE);			//读图
	namedWindow("src", WINDOW_FREERATIO);
	imshow("src", src);
	waitKey(0);
	
	Rect roi = Rect(500, 500, 2000, 2000);					//定义ROI大小
	Mat process = Mat(src, roi);							//取ROI图像
	namedWindow("process", WINDOW_FREERATIO);
	imshow("process", process);
	waitKey(0);
	
	Mat dst1 = Mat::zeros(2000, 2000, CV_8UC1);				//结果1
	Mat dst2 = Mat::zeros(2000, 2000, CV_8UC1);				//结果2
	Mat dst3 = Mat::zeros(2000, 2000, CV_8UC1);				//结果3

	/*方法1*/
	for (int i = 0; i < 2000; i++)
	{
		for (int j = 0; j < 2000; j++)
		{
			dst1.at<uchar>(i, j) = process.at<uchar>(i, j); //赋值
		}
	}


	/*方法2*/
	uchar* p_src = process.data;
	uchar* p_dst2 = dst2.data;
	for (int i = 0; i < 2000 * 2000; i++)
	{
		*(p_dst2 + i) = *(p_src + i);						//赋值
	}
	namedWindow("dst1", WINDOW_FREERATIO);
	imshow("dst1", dst1);
	namedWindow("dst2", WINDOW_FREERATIO);
	imshow("dst2", dst2);
	waitKey(0);


	/*方法2改正*/
	Mat process_clone = process.clone();
	uchar* p_src2 = process_clone.data;
	uchar* p_dst3 = dst3.data;
	for (int i = 0; i < 2000 * 2000; i++)
	{
		*(p_dst3 + i) = *(p_src2 + i);						//赋值
	}
	namedWindow("dst1", WINDOW_FREERATIO);
	imshow("dst1", dst1);
	namedWindow("dst2", WINDOW_FREERATIO);
	imshow("dst2", dst2);
	namedWindow("dst3", WINDOW_FREERATIO);
	imshow("dst3", dst3);
	waitKey(0);

	return 0;
}

测试结果

原图

在这里插入图片描述

取ROI后的图像

在这里插入图片描述

三种赋值方法的结果

在这里插入图片描述

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-05-12 16:27:40  更:2022-05-12 16:29:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:49:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码