日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

OpenCV(二)逐像素的图像复制、图像边缘检测(自实现和API实现)

發布時間:2023/11/27 生活经验 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。