OpenCV(二)逐像素的图像复制、图像边缘检测(自实现和API实现)
目录
一、逐像素的图像复制
1、代码
2、效果
二、简单的图像边缘检测(自实现)
0、图像处理的卷积运算
1、简单模糊处理
2、强化边缘处理
1、原理
2、代码
3、效果
三、简单的图像边缘检测(调用API)
1、设置卷积核kernel
2、利用filter()函数进行卷积运算
3、总代码
一、逐像素的图像复制
这里主要是为了强化图像的指针应用。
//图像的指针用法举例
cv::Mat image = cv::Mat(400, 600, CV_8UC1); //定义了一个Mat变量image。
uchar * data00 = image.ptr<uchar>(0); //data00是指向image第1行第1个元素的指针。
uchar * data10 = image.ptr<uchar>(1); //data10是指向image第1行第1个元素的指针。
uchar * data01 = image.ptr<uchar>(0)[1]; //data01是指向image第1行第2个元素的指针。
1、代码:
//逐像素的图像复制
#include <iostream>
#include <opencv2/opencv.hpp> using namespace cv;
using namespace std;
int main()
{int i, j;Mat img = imread("Resource/Lena.jpg");int channels = img.channels(); //通道数int cols = img.cols * channels; //列*通道数(每行需要的RGB)int rows = img.rows; //行数Mat New = Mat::zeros(img.size(), img.type()); //创建一张黑色的图const uchar* p = img.ptr<uchar>(0); //原图首地址uchar* pNew = New.ptr<uchar>(0); //新图首地址if (img.empty()) //判断图像存在{printf("could not load the image..");return -1;}for (i = 0; i < rows; i++){p = img.ptr<uchar>(i); //指向i行首元素pNew = New.ptr<uchar>(i); //指向j行首元素for (j = 0; j <= cols; j++){pNew[j] = p[j]; //pNew的i行j元素RGB赋值p的i行j元素RGB}}namedWindow("原始图像", WINDOW_AUTOSIZE);imshow("原始图像", img);namedWindow("修改后图像", WINDOW_AUTOSIZE);imshow("修改后图像", New);waitKey(0);return 0;
}
2、效果
二、简单的图像边缘检测(自实现)
0、图像处理的卷积运算
1、简单模糊处理
比如说,如下图像处理矩阵将使得图像变得更平滑,显得更模糊,因为它联合周边像素进行了平均处理:
2、强化边缘处理
而如下图像处理矩阵将使得像素值变化明显的地方更为明显,强化边缘,而变化平缓的地方没有影响,达到提取边缘的目的:
1、原理
在边缘处,留心观察发现会有RGB的突变,只需要把这个RGB突变部分给锐化,显示在对应位置即可。(其他部分淡化)
2、代码
//平滑处理
#include <iostream>
#include <opencv2/opencv.hpp> using namespace cv;
using namespace std;
int main()
{int i, j;Mat img = imread("Resource/Lena.jpg");if (img.empty()){printf("could not load the image..");return -1;}int cols = img.cols * img.channels(); //列*通道数int rows = img.rows; //行数int channels = img.channels(); //通道数Mat New = Mat::zeros(img.size(), img.type()); //创建一张黑色的图const uchar* p; //原图当前行首地址(暂时无指向)const uchar* prior; //原图上一行首地址(暂时无指向)const uchar* next; //原图下一行首地址(暂时无指向)uchar* pNew; //新图当前行首地址(暂时无指向)//按行处理(每行首和尾不做处理)for (i = 1; i < rows - 1; i++){p = img.ptr<uchar>(i); //原图当前行首地址prior = img.ptr<uchar>(i - 1); //原图上一行首地址next = img.ptr<uchar>(i + 1); //原图下一行首地址pNew = New.ptr<uchar>(i); //新图当前行首地址//按列处理(每列首和尾不做处理)for (j = 0 + channels; j <= cols - channels; j++){pNew[j] = saturate_cast <uchar>(4 * p[j] - prior[j] - next[j] - p[j - channels] - p[j + channels]);// 限制RGB范围(0~255) //p[j]:当前行当前列元素 //prior[j]:上一行当前列元素 //next[j]:下一行当前列元素// p[j - channels]:上一列像素(不是RGB) //p[j + channels]:下一列像素(不是RGB)}}namedWindow("修改前图像", WINDOW_AUTOSIZE);imshow("修改前图像", img);namedWindow("修改后图像", WINDOW_AUTOSIZE);imshow("修改后图像", New);waitKey(0);return 0;
}
3、效果
三、简单的图像边缘检测(调用API)
1、设置卷积核kernel
//1、初始化卷积核Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 4, -1, 0, -1, 0);
2、利用filter()函数进行卷积运算
filter2D(img, New, img.depth(), kernel);
// 原图,目标图,深度, 卷积核
3、总代码
//边缘检测
#include <iostream>
#include <opencv2/opencv.hpp> using namespace cv;
using namespace std;Mat img = imread("Resource/Lena.jpg"); //读取图像
int cols = img.cols * img.channels(); //列*通道数
int rows = img.rows; //行数
int channels = img.channels(); //通道数
Mat New = Mat::zeros(img.size(), img.type()); //创建一张黑色的图//判断图像是否存在
int JudgeImage()
{if (img.empty()){printf("could not load the image..");return -1;}
}//边缘化
void Marginalize()
{int i, j;const uchar* p; //原图当前行首地址(暂时无指向)const uchar* prior; //原图上一行首地址(暂时无指向)const uchar* next; //原图下一行首地址(暂时无指向)uchar* pNew; //新图当前行首地址(暂时无指向)//按行处理(每行首和尾不做处理)for (i = 1; i < rows - 1; i++){p = img.ptr<uchar>(i); //原图当前行首地址prior = img.ptr<uchar>(i - 1); //原图上一行首地址next = img.ptr<uchar>(i + 1); //原图下一行首地址pNew = New.ptr<uchar>(i); //新图当前行首地址//按列处理(每列首和尾不做处理)for (j = 0 + channels; j <= cols - channels; j++){pNew[j] = saturate_cast <uchar>(4 * p[j] - prior[j] - next[j] - p[j - channels] - p[j + channels]);// 限制RGB范围(0~255) //p[j]:当前行当前列元素 prior[j]:上一行当前列元素 next[j]:下一行当前列元素// p[j - channels]:上一列像素(不是RGB) p[j + channels]:下一列像素(不是RGB)}}
}//打印卷积核
void ShowKernel(Mat kernel)
{printf("卷积核:\n");//打印卷积核for (int i = 0; i < 3; i++){for (int j = 0; j < 3; j++){printf("%3d", kernel.at<char>(i, j));}printf("\n");}
}//调用API边缘化
void API_Marginalize()
{//1、初始化卷积核Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 4, -1, 0, -1, 0); //2、卷积运算filter2D(img, New, img.depth(), kernel); // 原图,目标图,深度, 卷积核//打印卷积核//ShowKernel(kernel);
}//显示图像
void Show()
{namedWindow("修改前图像", WINDOW_AUTOSIZE);imshow("修改前图像", img);namedWindow("修改后图像", WINDOW_AUTOSIZE);imshow("修改后图像", New);
}int main()
{JudgeImage(); //判断图像是否存在//Marginalize(); //边缘化图像API_Marginalize(); //调用API边缘化Show(); //显示图像waitKey(0);return 0;
}
有出错的地方欢迎大家纠错!
OpenCV(二)逐像素的图像复制、图像边缘检测(自实现和API实现)相关推荐
- [Python图像处理] 三十五.OpenCV图像处理入门、算数逻辑运算与图像融合(推荐)
该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...
- OpenCV(总结篇)图像逐像素访问(三种操作:指针、迭代器、at()函数)
目录 概述 1.指针访问 2.迭代器访问 3.at()函数访问 总代码 效果 参考资料 概述 访问图像像素值是图像处理的基本操作.OpenCV提供了很多访问方式,比较常用的三种方式: (1) 通过指 ...
- opencv(二)图像像素提取及操作
为了编写计算机视觉应用,我们必须会存取图像的内容,如修改或者创建图像,这些过程都需要对图像的基本元素进行操作,即所谓的像素. 1[存取像素值] 为了存取矩阵元素,我们需要在代码中指定元素所在的行和列, ...
- opencv 二维图像 特征检测 特征描述 特征匹配 平面物体识别跟踪
github代码 一.Harris角点 cornerHarris() R = det(M) - k*(trace(M))^2 算法基本思想是使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与 ...
- OpenCV删除面积小的区域 实现图像二值化分割 标记连通区域
OpenCV删除面积小的区域 实现图像二值化分割 标记连通区域 [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/781 ...
- python+OpenCV图像处理(十二)车牌定位中对图像的形态学组合操作处理
车牌定位中对图像的形态学组合操作处理 所谓的车牌定位,其中最关键的部分就是对图片的处理,参数的设置,并使之拥有泛化能力. 首先传入图片,在进行大规模的图片处理时,因为无法确定图片的尺寸,所以需要将原始 ...
- python opencv图像二值化函数_python opencv 二值化 计算白色像素点的实例
python opencv 二值化 计算白色像素点的实例 贴部分代码 #! /usr/bin/env python # -*- coding: utf-8 -*- import cv2 import ...
- cv图像预处理——逐像素变换
cv图像预处理--逐像素变换 标签:计算机视觉 逐像素变换 对图像中的每个像素逐个进行处理. 白化(类似于标准化) 白化的目的是要为图像的平均亮度水平和对比度提供波动的恒定性.其中每个像素进行如下转换 ...
- android都图片mat_计算机视觉 OpenCV Android | Mat像素操作(图像像素的读写、均值方差、算术、逻辑等运算、权重叠加、归一化等操作)...
本文目录 1. 像素读写 2. 图像通道与均值方差计算 3. 算术操作与调整图像的亮度和对比度 4. 基于权重的图像叠加 5. Mat的其他各种像素操作 1. 像素读写 Mat作为图像容器,其数据部分 ...
最新文章
- python语言必背代码-Python入门必须知道的11个知识点
- UA MATH567 高维统计II 随机向量8 图的Max-cut问题 0.5近似算法的运行时间分析
- mongodb 监控项详解(mms)
- JavaScript实现截留雨水问题的蛮力方法的算法(附完整源码)
- solr mysql增量导入_Solr全量与增量导入
- 2011年7月20日 14:32:41
- 我的第一个项目催生的前世今生(LAIS,LKJ,DTU,记录器)
- c语言简易计算器大作业报告,简易计算器 (C语言)作业
- 四川师范大学地信概论(3- 空间数据模型)90分以上版本
- 成都-峨眉山(乐山)旅游攻略
- 温湿度传感器—HDC1080
- 除了性以外,有没有快速、高效的释放压力、清空大脑的方式?
- qq离线linux,QQ For Linux 我哭了,官方版
- 倾斜摄影 镜头畸变校准_什么是风景摄影的最佳镜头?
- 【原创】从BZOJ2683 简单题中 整 CDQ分治解决三维偏序
- --仿蓝色理想网站的导航菜单--
- Java PDF数字签名(一) - 添加数字签名
- 比较两个Integer的值是否相等
- 一本通1652牡牛和牝牛
- 【NOIP2016普及组】买铅笔
热门文章
- Java return 关键字的使用
- Excution failed for task ':app:transformClassWithDexForDebug'
- mqtt+htttp+websocket
- ThinkPHP5.1接收post、get参数
- python基础之生成器,生成器函数,列表推导式
- MySQL☞dual虚拟表
- AJAX跨域访问解决方案
- Oracle常用傻瓜问题1000问
- java某市出租车_智慧职教mooc的APPJavaEE企业级网站开发章节测验答案
- 技嘉主板bios设置键盘不能用_BIOS不再硬梆梆、全新技嘉主板BIOS设置就算不是玩家也能轻松搞定...