日韩在线不卡一区二区三区四区五区,欧美视频一区二区三,欧美视频中文字幕一区二区,高端 精品 国产 探花,亚欧无吗一二三四五六区
RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
C++手敲Roberts-創(chuàng)新互聯(lián)

使用OPENCV,編寫代碼,學(xué)習(xí)圖像二值化算法,以及邊緣檢測算法,進(jìn)行圖像的分割。

站在用戶的角度思考問題,與客戶深入溝通,找到城中網(wǎng)站設(shè)計(jì)與城中網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、申請域名、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋城中地區(qū)。

下面主要介紹Robert算子的實(shí)現(xiàn)過程:

①任務(wù)分析

調(diào)入并顯示圖像;使用Roberts 算子對圖像進(jìn)行邊緣檢測處理; Roberts 算子為一對模板:

c35d8dfb3e764d80981995b7803370d9.png

相應(yīng)的矩陣為:rh = [0 1;-1 0];?rv = [1 0;0 -1];這里的rh 為水平Roberts 算子,rv為垂直Roberts 算子。分別顯示處理后的水平邊界和垂直邊界檢測結(jié)果;用“歐幾里德距離”和“街區(qū)距離”方式計(jì)算梯度的模,并顯示檢測結(jié)果;對于檢測結(jié)果進(jìn)行二值化處理,并顯示處理結(jié)果。

②代碼實(shí)現(xiàn)

先加載需要的庫

#include#includeusing namespace cv;

接著定義一個(gè)基于Roberts算子實(shí)現(xiàn)閾值分割的函數(shù),其功能包括顯示用街區(qū)距離和歐幾里得距離得出的梯度圖、選擇一個(gè)合適的閾值實(shí)現(xiàn)圖像分割。
其中街區(qū)距離就是水平梯度和垂直梯度的和:

Robert_City.at(row, col) = saturate_cast(fabs(img.at(row, col) - img.at(row + 1, col + 1))+ fabs(img.at(row, col + 1) - img.at(row + 1, col)));

saturate_cast()函數(shù)的作用是限制像素值的范圍,把大于255和小于0的情況分別賦值255和0,避免了像素值溢出的問題。

而歐幾里得距離就是水平梯度和垂直梯度的平方和再開方:

Robert_Ojld.at(row, col) = saturate_cast(sqrt(pow(img.at(row, col) - img.at(row + 1, col + 1),2) + pow(img.at(row, col + 1) - img.at(row + 1, col),2)));

具體代碼實(shí)現(xiàn):

Mat Robert_City = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算城市距離的空白圖像
	Mat Robert_Ojld = Mat::zeros(Size(img.rows, img.cols), img.type());  //用于計(jì)算歐幾里得距離的空白圖像
	for (int row = 0; row< img.rows-1; row++) {
		for (int col = 0; col< img.cols-1; col++) {                 // 由于像素之間的加減可能會小于零,因此記得加上絕對值函數(shù)fabs()
			Robert_City.at(row, col) = saturate_cast(fabs(img.at(row, col) - img.at(row + 1, col + 1)) + fabs(img.at(row, col + 1) - img.at(row + 1, col)));
		}
	}
	for (int row = 0; row< img.rows - 1; row++) {
		for (int col = 0; col< img.cols - 1; col++) {
			Robert_Ojld.at(row, col) = saturate_cast(sqrt(pow(img.at(row, col) - img.at(row + 1, col + 1),2) + pow(img.at(row, col + 1) - img.at(row + 1, col),2)));
		}
	}
	imshow("Robert圖像(街區(qū)距離)", Robert_City);
	imshow("Robert圖像(歐幾里得距離)", Robert_Ojld);

結(jié)果如下:

bf4442d47066443fb3205fb0c54c008b.png(原圖)
ca9a9c1fac0e443990fdf5dca253273e.png8937aa6f6d434416881a7551e58c62d5.png

接下來要選擇一個(gè)合適的閾值用于圖像的二值化。選擇閾值的方式有很多暴力遍歷(不推薦)、調(diào)用函數(shù)法(直接輸出直方圖看每一個(gè)像素值的數(shù)量,方便主觀判斷)和數(shù)組法。這里介紹一下數(shù)組法:創(chuàng)建一個(gè)256大小的一維數(shù)組arr[256],每一個(gè)元素依據(jù)索引代表對應(yīng)的像素值的個(gè)數(shù)。就比如說假設(shè)一共有10000個(gè)點(diǎn)像素值為0,那么arr[0] = 10000。先對歐幾里得距離實(shí)現(xiàn)二值化,實(shí)現(xiàn)如下:

int pixel_num[256] = {0};            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows ; row++) {
		for (int col = 0; col< img.cols ; col++) {         
			pixel_num[Robert_Ojld.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int times = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<<"像素值"<

輸出結(jié)果:
766367b54f6a4c0aaf01f857a8a8df1b.png

可以看出,像素值9和像素值10差異變化較大。因此可以選擇像素值10作為分割圖像的閾值,比像素值10小的像素全部賦值為0,比像素值大的全部賦值255:

for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Robert_Ojld.at(row, col)< 10) {
				Robert_Ojld.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Robert_Ojld.at(row, col) = 255;
			}
		}
	}
	imshow("歐幾里得閾值分割", Robert_Ojld);

345edbb7b0af4949b2b06f6fa1c34b0d.png

可以看到閾值分割效果不錯(cuò),但是不足之處也很明顯:圖像因此留下了很多離散點(diǎn),這是閾值選擇得不夠大的原因。于是我又偷偷的把閾值調(diào)整為15:
3771e8982e294de39f4d33b87df4fc5e.png在保證圖片不失真的情況下,15作為閾值要明顯好于10。

同理,街區(qū)距離的做法和歐幾里得距離類似,也是通過數(shù)組得到較為可信的閾值之后再細(xì)微調(diào)整。
街區(qū)距離的實(shí)現(xiàn)過程以及結(jié)果如下所示:

int pixel_num02[256] = { 0 };            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {
			pixel_num01[Robert_City.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int time = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<< "像素值"<< time<< "的數(shù)目為:  "<< pixel_num02[time]<< endl;    // 遍歷輸出
		time++;                             // 不要忘了自增
	}
	//得到10作為分割閾值
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Robert_City.at(row, col)< 20) {
				Robert_City.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Robert_City.at(row, col) = 255;
			}
		}
	}
	imshow("街區(qū)距離閾值分割", Robert_City);

cf1a2a1d009140b1980a728e08af0f34.png

注意:閾值的選擇是很關(guān)鍵的,如果閾值選擇過大的話可能會導(dǎo)致邊緣斷開的情況,也就是失真。這就需要我們在去噪和失真兩個(gè)方面做權(quán)衡。以下給出了基于Roberts算子的閾值分割函數(shù)的完整代碼:

void Roberts(Mat& img) {                   // 基于Roberts算子的閾值分割
	Mat Robert_City = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算城市距離的空白圖像
	Mat Robert_Ojld = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算歐幾里得距離的空白圖像
	for (int row = 0; row< img.rows-1; row++) {
		for (int col = 0; col< img.cols-1; col++) {                 // 由于像素之間的加減可能會小于零,因此記得加上絕對值函數(shù)fabs()
			Robert_City.at(row, col) = saturate_cast(fabs(img.at(row, col) - img.at(row + 1, col + 1)) + fabs(img.at(row, col + 1) - img.at(row + 1, col)));
		}
	}
	for (int row = 0; row< img.rows - 1; row++) {
		for (int col = 0; col< img.cols - 1; col++) {
			Robert_Ojld.at(row, col) = saturate_cast(sqrt(pow(img.at(row, col) - img.at(row + 1, col + 1),2) + pow(img.at(row, col + 1) - img.at(row + 1, col),2)));
		}
	}
	imshow("Robert圖像(街區(qū)距離)", Robert_City);
	imshow("Robert圖像(歐幾里得距離)", Robert_Ojld);
	int pixel_num01[256] = {0};            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows ; row++) {
		for (int col = 0; col< img.cols ; col++) {         
			pixel_num01[Robert_Ojld.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int times = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<<"像素值"<(row, col)< 15) {
				Robert_Ojld.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Robert_Ojld.at(row, col) = 255;
			}
		}
	}
	imshow("歐幾里得閾值分割", Robert_Ojld);
	int pixel_num02[256] = { 0 };            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {
			pixel_num01[Robert_City.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int time = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<< "像素值"<< time<< "的數(shù)目為:  "<< pixel_num02[time]<< endl;    // 遍歷輸出
		time++;                             // 不要忘了自增
	}
	//得到10作為分割閾值
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Robert_City.at(row, col)< 20) {
				Robert_City.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Robert_City.at(row, col) = 255;
			}
		}
	}
	imshow("街區(qū)距離閾值分割", Robert_City);

	waitKey(0);
	destroyAllWindows();
}

類似的如Prewitt算子、Sobel算子與上述的Roberts算子類似,其閾值分割的過程都是先用街區(qū)距離、歐幾里得距離分別算出原始圖像的梯度,然后再創(chuàng)建一個(gè)一維數(shù)組來記錄下每個(gè)像素值的數(shù)目以備接下來的閾值選擇操作。最后的閾值選擇既需要能有效地對圖像進(jìn)行分割,也要保證圖像不會出現(xiàn)失真的現(xiàn)象。

以下分別是基于Prewitt算子的閾值分割函數(shù)、基于Sobel算子的閾值分割函數(shù)。

void Prewitt(Mat& img) {                   // 基于Prewitt算子的閾值分割
	Mat Prewitt_City = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算城市距離的空白圖像
	Mat Prewitt_Ojld = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算歐幾里得距離的空白圖像
	for (int row = 1; row< img.rows - 1; row++) {
		for (int col = 1; col< img.cols - 1; col++) {                 // 由于像素之間的加減可能會小于零,因此記得加上絕對值函數(shù)fabs()
			Prewitt_City.at(row, col) = saturate_cast(fabs(img.at(row-1, col+1) - img.at(row - 1, col - 1)+ img.at(row , col + 1)- img.at(row, col - 1)+ img.at(row + 1, col + 1)- img.at(row + 1, col - 1)) + fabs(img.at(row+1, col - 1) - img.at(row -1 , col-1)+ img.at(row + 1, col)- img.at(row - 1, col)+ img.at(row + 1, col + 1)- img.at(row - 1, col + 1)));
		}
	}
	for (int row = 1; row< img.rows - 1; row++) {
		for (int col = 1; col< img.cols - 1; col++) {
			Prewitt_Ojld.at(row, col) = saturate_cast(sqrt(pow(img.at(row - 1, col + 1) - img.at(row - 1, col - 1) + img.at(row, col + 1) - img.at(row, col - 1)+ img.at(row + 1, col + 1) - img.at(row + 1, col - 1), 2) + pow(img.at(row + 1, col - 1) - img.at(row - 1, col - 1) + img.at(row + 1, col) - img.at(row - 1, col) + img.at(row + 1, col + 1) - img.at(row - 1, col + 1), 2)));
		}
	}
	imshow("Prewitt圖像(街區(qū)距離)", Prewitt_City);
	imshow("Prewitt圖像(歐幾里得距離)", Prewitt_Ojld);
	int pixel_num01[256] = { 0 };            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {
			pixel_num01[Prewitt_Ojld.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int times = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<< "像素值"<< times<< "的數(shù)目為:  "<< pixel_num01[times]<< endl;    // 遍歷輸出
		times++;                             // 不要忘了自增
	}
	//得到10作為分割閾值
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Prewitt_Ojld.at(row, col)< 70) {
				Prewitt_Ojld.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Prewitt_Ojld.at(row, col) = 255;
			}
		}
	}
	imshow("歐幾里得閾值分割", Prewitt_Ojld);
	int pixel_num02[256] = { 0 };            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {
			pixel_num01[Prewitt_City.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int time = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<< "像素值"<< time<< "的數(shù)目為:  "<< pixel_num02[time]<< endl;    // 遍歷輸出
		time++;                             // 不要忘了自增
	}
	//得到10作為分割閾值
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Prewitt_City.at(row, col)< 70) {
				Prewitt_City.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Prewitt_City.at(row, col) = 255;
			}
		}
	}
	imshow("街區(qū)距離閾值分割", Prewitt_City);

	waitKey(0);
	destroyAllWindows();
}
void Sobel(Mat& img) {                   // 基于Prewitt算子的閾值分割
	Mat Sobel_City = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算城市距離的空白圖像
	Mat Sobel_Ojld = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算歐幾里得距離的空白圖像
	for (int row = 1; row< img.rows - 1; row++) {
		for (int col = 1; col< img.cols - 1; col++) {                 // 由于像素之間的加減可能會小于零,因此記得加上絕對值函數(shù)fabs()
			Sobel_City.at(row, col) = saturate_cast(fabs(img.at(row - 1, col + 1) - img.at(row - 1, col - 1) + 2*img.at(row, col + 1) - 2*img.at(row, col - 1) + img.at(row + 1, col + 1) - img.at(row + 1, col - 1)) + fabs(img.at(row + 1, col - 1) - img.at(row - 1, col - 1) + 2*img.at(row + 1, col) - 2*img.at(row - 1, col) + img.at(row + 1, col + 1) - img.at(row - 1, col + 1)));
		}
	}
	for (int row = 1; row< img.rows - 1; row++) {
		for (int col = 1; col< img.cols - 1; col++) {
			Sobel_Ojld.at(row, col) = saturate_cast(sqrt(pow(img.at(row - 1, col + 1) - img.at(row - 1, col - 1) + 2*img.at(row, col + 1) - 2*img.at(row, col - 1) + img.at(row + 1, col + 1) - img.at(row + 1, col - 1), 2) + pow(img.at(row + 1, col - 1) - img.at(row - 1, col - 1) + 2*img.at(row + 1, col) - 2*img.at(row - 1, col) + img.at(row + 1, col + 1) - img.at(row - 1, col + 1), 2)));
		}
	}
	imshow("Sobel圖像(街區(qū)距離)", Sobel_City);
	imshow("Sobel圖像(歐幾里得距離)", Sobel_Ojld);
	int pixel_num01[256] = { 0 };            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {
			pixel_num01[Sobel_Ojld.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int times = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<< "像素值"<< times<< "的數(shù)目為:  "<< pixel_num01[times]<< endl;    // 遍歷輸出
		times++;                             // 不要忘了自增
	}
	//得到10作為分割閾值
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Sobel_Ojld.at(row, col)< 70) {
				Sobel_Ojld.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Sobel_Ojld.at(row, col) = 255;
			}
		}
	}
	imshow("歐幾里得閾值分割", Sobel_Ojld);
	int pixel_num02[256] = { 0 };            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {
			pixel_num01[Sobel_City.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int time = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<< "像素值"<< time<< "的數(shù)目為:  "<< pixel_num02[time]<< endl;    // 遍歷輸出
		time++;                             // 不要忘了自增
	}
	//得到10作為分割閾值
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Sobel_City.at(row, col)< 70) {
				Sobel_City.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Sobel_City.at(row, col) = 255;
			}
		}
	}
	imshow("街區(qū)距離閾值分割", Sobel_City);

	waitKey(0);
	destroyAllWindows();
}

Prewitt算子和Sobel算子大同小異,Sobel是在Prewitt的基礎(chǔ)上增加了權(quán)重,也就是越靠近當(dāng)前像素值,那么它所發(fā)揮的作用就越大??傮w而言的話Prewitt算子和Sobel算子的結(jié)果會比Roberts算子的結(jié)果要好一些,下面是基于兩者的閾值分割結(jié)果:
a53dcba6284848f0b916f72e7f86d7d7.png

791bb3e6794e4b2db0895b53ebdbc300.png

2df23ca6a48f431ebeffae46e76e263a.png40f291bad9674e398fb4d4ba3e817d63.png

總代碼如下:

#include#include#includeusing namespace cv;
using namespace std;

void Roberts(Mat& img);
void Prewitt(Mat& img);
void Sobel(Mat& img);

int main() {
	Mat Gray = imread("C:\\Users\\Czhannb\\Desktop\\gray.png", IMREAD_GRAYSCALE);
	if (Gray.empty()) {
		cout<< "讀取圖片錯(cuò)誤!"<< endl;
	}
	else {
		imshow("未動工之前:", Gray);
	}
	//Roberts(Gray);
	//Prewitt(Gray);
	Sobel(Gray);
	return 0;
}


void Roberts(Mat& img) {                   // 基于Roberts算子的閾值分割
	Mat Robert_City = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算城市距離的空白圖像
	Mat Robert_Ojld = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算歐幾里得距離的空白圖像
	for (int row = 0; row< img.rows-1; row++) {
		for (int col = 0; col< img.cols-1; col++) {                 // 由于像素之間的加減可能會小于零,因此記得加上絕對值函數(shù)fabs()
			Robert_City.at(row, col) = saturate_cast(fabs(img.at(row, col) - img.at(row + 1, col + 1)) + fabs(img.at(row, col + 1) - img.at(row + 1, col)));
		}
	}
	for (int row = 0; row< img.rows - 1; row++) {
		for (int col = 0; col< img.cols - 1; col++) {
			Robert_Ojld.at(row, col) = saturate_cast(sqrt(pow(img.at(row, col) - img.at(row + 1, col + 1),2) + pow(img.at(row, col + 1) - img.at(row + 1, col),2)));
		}
	}
	imshow("Robert圖像(街區(qū)距離)", Robert_City);
	imshow("Robert圖像(歐幾里得距離)", Robert_Ojld);
	int pixel_num01[256] = {0};            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows ; row++) {
		for (int col = 0; col< img.cols ; col++) {         
			pixel_num01[Robert_Ojld.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int times = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<<"像素值"<(row, col)< 15) {
				Robert_Ojld.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Robert_Ojld.at(row, col) = 255;
			}
		}
	}
	imshow("歐幾里得閾值分割", Robert_Ojld);
	int pixel_num02[256] = { 0 };            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {
			pixel_num01[Robert_City.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int time = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<< "像素值"<< time<< "的數(shù)目為:  "<< pixel_num02[time]<< endl;    // 遍歷輸出
		time++;                             // 不要忘了自增
	}
	//得到10作為分割閾值
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Robert_City.at(row, col)< 20) {
				Robert_City.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Robert_City.at(row, col) = 255;
			}
		}
	}
	imshow("街區(qū)距離閾值分割", Robert_City);

	waitKey(0);
	destroyAllWindows();
}

void Prewitt(Mat& img) {                   // 基于Prewitt算子的閾值分割
	Mat Prewitt_City = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算城市距離的空白圖像
	Mat Prewitt_Ojld = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算歐幾里得距離的空白圖像
	for (int row = 1; row< img.rows - 1; row++) {
		for (int col = 1; col< img.cols - 1; col++) {                 // 由于像素之間的加減可能會小于零,因此記得加上絕對值函數(shù)fabs()
			Prewitt_City.at(row, col) = saturate_cast(fabs(img.at(row-1, col+1) - img.at(row - 1, col - 1)+ img.at(row , col + 1)- img.at(row, col - 1)+ img.at(row + 1, col + 1)- img.at(row + 1, col - 1)) + fabs(img.at(row+1, col - 1) - img.at(row -1 , col-1)+ img.at(row + 1, col)- img.at(row - 1, col)+ img.at(row + 1, col + 1)- img.at(row - 1, col + 1)));
		}
	}
	for (int row = 1; row< img.rows - 1; row++) {
		for (int col = 1; col< img.cols - 1; col++) {
			Prewitt_Ojld.at(row, col) = saturate_cast(sqrt(pow(img.at(row - 1, col + 1) - img.at(row - 1, col - 1) + img.at(row, col + 1) - img.at(row, col - 1)+ img.at(row + 1, col + 1) - img.at(row + 1, col - 1), 2) + pow(img.at(row + 1, col - 1) - img.at(row - 1, col - 1) + img.at(row + 1, col) - img.at(row - 1, col) + img.at(row + 1, col + 1) - img.at(row - 1, col + 1), 2)));
		}
	}
	imshow("Prewitt圖像(街區(qū)距離)", Prewitt_City);
	imshow("Prewitt圖像(歐幾里得距離)", Prewitt_Ojld);
	int pixel_num01[256] = { 0 };            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {
			pixel_num01[Prewitt_Ojld.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int times = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<< "像素值"<< times<< "的數(shù)目為:  "<< pixel_num01[times]<< endl;    // 遍歷輸出
		times++;                             // 不要忘了自增
	}
	//得到10作為分割閾值
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Prewitt_Ojld.at(row, col)< 70) {
				Prewitt_Ojld.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Prewitt_Ojld.at(row, col) = 255;
			}
		}
	}
	imshow("歐幾里得閾值分割", Prewitt_Ojld);
	int pixel_num02[256] = { 0 };            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {
			pixel_num01[Prewitt_City.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int time = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<< "像素值"<< time<< "的數(shù)目為:  "<< pixel_num02[time]<< endl;    // 遍歷輸出
		time++;                             // 不要忘了自增
	}
	//得到10作為分割閾值
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Prewitt_City.at(row, col)< 70) {
				Prewitt_City.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Prewitt_City.at(row, col) = 255;
			}
		}
	}
	imshow("街區(qū)距離閾值分割", Prewitt_City);

	waitKey(0);
	destroyAllWindows();
}

void Sobel(Mat& img) {                   // 基于Prewitt算子的閾值分割
	Mat Sobel_City = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算城市距離的空白圖像
	Mat Sobel_Ojld = Mat::zeros(Size(img.cols, img.rows), img.type());  //用于計(jì)算歐幾里得距離的空白圖像
	for (int row = 1; row< img.rows - 1; row++) {
		for (int col = 1; col< img.cols - 1; col++) {                 // 由于像素之間的加減可能會小于零,因此記得加上絕對值函數(shù)fabs()
			Sobel_City.at(row, col) = saturate_cast(fabs(img.at(row - 1, col + 1) - img.at(row - 1, col - 1) + 2*img.at(row, col + 1) - 2*img.at(row, col - 1) + img.at(row + 1, col + 1) - img.at(row + 1, col - 1)) + fabs(img.at(row + 1, col - 1) - img.at(row - 1, col - 1) + 2*img.at(row + 1, col) - 2*img.at(row - 1, col) + img.at(row + 1, col + 1) - img.at(row - 1, col + 1)));
		}
	}
	for (int row = 1; row< img.rows - 1; row++) {
		for (int col = 1; col< img.cols - 1; col++) {
			Sobel_Ojld.at(row, col) = saturate_cast(sqrt(pow(img.at(row - 1, col + 1) - img.at(row - 1, col - 1) + 2*img.at(row, col + 1) - 2*img.at(row, col - 1) + img.at(row + 1, col + 1) - img.at(row + 1, col - 1), 2) + pow(img.at(row + 1, col - 1) - img.at(row - 1, col - 1) + 2*img.at(row + 1, col) - 2*img.at(row - 1, col) + img.at(row + 1, col + 1) - img.at(row - 1, col + 1), 2)));
		}
	}
	imshow("Sobel圖像(街區(qū)距離)", Sobel_City);
	imshow("Sobel圖像(歐幾里得距離)", Sobel_Ojld);
	int pixel_num01[256] = { 0 };            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {
			pixel_num01[Sobel_Ojld.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int times = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<< "像素值"<< times<< "的數(shù)目為:  "<< pixel_num01[times]<< endl;    // 遍歷輸出
		times++;                             // 不要忘了自增
	}
	//得到10作為分割閾值
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Sobel_Ojld.at(row, col)< 70) {
				Sobel_Ojld.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Sobel_Ojld.at(row, col) = 255;
			}
		}
	}
	imshow("歐幾里得閾值分割", Sobel_Ojld);
	int pixel_num02[256] = { 0 };            //數(shù)組記得初始化為0,即未統(tǒng)計(jì)數(shù)量之前各個(gè)像素的個(gè)數(shù)都是0
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {
			pixel_num01[Sobel_City.at(row, col)] += 1;   //遍歷到的像素值作為索引,次數(shù)+1
		}
	}
	int time = 0;         //定義遍歷數(shù)組的變量,從0開始,依次輸出0到255每個(gè)像素值的數(shù)目
	while (times<= 255) {
		cout<< "像素值"<< time<< "的數(shù)目為:  "<< pixel_num02[time]<< endl;    // 遍歷輸出
		time++;                             // 不要忘了自增
	}
	//得到10作為分割閾值
	for (int row = 0; row< img.rows; row++) {
		for (int col = 0; col< img.cols; col++) {       //遍歷所有像素點(diǎn)進(jìn)行判斷
			if (Sobel_City.at(row, col)< 70) {
				Sobel_City.at(row, col) = 0;     // 小于閾值賦值為0,否則賦值255
			}
			else {
				Sobel_City.at(row, col) = 255;
			}
		}
	}
	imshow("街區(qū)距離閾值分割", Sobel_City);

	waitKey(0);
	destroyAllWindows();
}

補(bǔ)充:
由于處理空白圖像的像素值時(shí)沒有考慮到最外面的一層,因此會出現(xiàn)有像素保持為初始值0的情況。一種改進(jìn)的方法是給這些像素賦值為離它最近的像素值,這樣的話一定程度上解決了邊界全黑的問題。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


網(wǎng)頁標(biāo)題:C++手敲Roberts-創(chuàng)新互聯(lián)
本文鏈接:http://biofuelwatch.net/article/dpgpeh.html
日韩在线不卡一区二区三区四区五区,欧美视频一区二区三,欧美视频中文字幕一区二区,高端 精品 国产 探花,亚欧无吗一二三四五六区