C++ Opencv——色形紋+SVM檢測綜合
阿新 • • 發佈:2018-12-21
目錄
主函式
#include <opencv2/opencv.hpp> #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> #include <iostream> #include "Water_Cut.h" #include "Feature.h" using namespace cv; using namespace std; using namespace cv::ml; Feature feature_class; int main() { // 訓練——訓練時候關閉測試 #if 0 // 遍歷圖片——為了迴圈提取特徵用 string train_img_dir = "C:\\Users\\Administrator\\Desktop\\樣品\\訓練"; string train_img_namehead = "test"; string train_img_type = "bmp"; //size_t train_img_num = 4; string img_name = train_img_dir + "\\" + "*." + train_img_type; //cout << img_name << endl; int train_img_num = feature_class.read_images_in_folder(img_name); cout << "訓練圖個數:" << train_img_num << endl; // 訓練用的輸入和標籤 Mat trainmat; trainmat = cv::Mat::zeros(train_img_num, 32, CV_32FC1); Mat labelmat; labelmat = cv::Mat::zeros(train_img_num, 1, CV_32SC1); // 遍歷圖並提取特徵 vector<Mat> train_img = feature_class.data_search(train_img_dir, train_img_namehead, train_img_type, train_img_num); for (size_t i = 0; i < train_img_num; i++) { resize(train_img[i], train_img[i], Size(train_img[i].cols / 2, train_img[i].rows / 2)); namedWindow("vetmat", 0); imshow("vetmat", train_img[i]);//train_img[i].clone(); waitKey(0); // 影象分割 Mat src = train_img[i].clone(); Mat dst = Mat::zeros(train_img[i].size(), CV_8UC3); Mat edge = Mat::zeros(train_img[i].size(), CV_8UC3); Water_Cut(src, dst, edge); // 影象特徵_HU Mat hu_dst = dst.clone(); double Hu[7] = { 0 }; feature_class.feature_hu(hu_dst, Hu); // 影象特徵_COLOR Mat color_dst = dst.clone(); float Mom[9] = { 0 }; feature_class.feature_color(color_dst, Mom); // 影象特徵_GLCM Mat glcm_dst = dst.clone(); cv::cvtColor(glcm_dst, glcm_dst, CV_RGB2GRAY); float glcm_data[16] = { 0 }; feature_class.feature_glcm(glcm_dst, glcm_data); float train_data[32] = { 0 }; for (size_t j = 0; j < 7; j++) { train_data[j] = (float)Hu[j]; } for (size_t j = 0; j < 9; j++) { train_data[7 + j] = (float)Mom[j]; } for (size_t j = 0; j < 16; j++) { train_data[16 + j] = (float)glcm_data[j]; } vector<float> traindata; // 特徵值——一類(一張圖)的特徵 for (size_t k = 0; k < 32; k++) { traindata.push_back(train_data[k]); } std::cout << "traindata size:"; std::cout << traindata.size() << endl; for (size_t j = 0; j < traindata.size(); j++) { trainmat.at<float>(i, j) = traindata[j]; } labelmat.at<int>(i, 0) = i + 1; //每張一類 } // 訓練的初始化 Ptr<SVM> svm = SVM::create(); svm->setType(SVM::C_SVC); svm->setKernel(SVM::LINEAR); svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6)); std::cout << "開始訓練" << endl; svm->train(trainmat, ROW_SAMPLE, labelmat); std::cout << "開始結束" << endl; svm->save("svm.xml"); #endif // 測試——測試時候關閉訓練 #if 1 // 遍歷測試檔案 // 遍歷圖片——為了迴圈提取特徵用 //string test_img_dir = "C:\\Users\\Administrator\\Desktop\\樣品\\測試\\方格1號"; //string test_img_dir = "C:\\Users\\Administrator\\Desktop\\樣品\\測試\\花紋2號"; //string test_img_dir = "C:\\Users\\Administrator\\Desktop\\樣品\\測試\\空紋理3號"; //string test_img_dir = "C:\\Users\\Administrator\\Desktop\\樣品\\測試\\條紋4號"; string test_img_dir = "C:\\Users\\Administrator\\Desktop\\樣品\\測試\\"; string test_img_namehead = "test"; string test_img_type = "bmp"; string img_name = test_img_dir + "\\" + "*." + test_img_type; //cout << img_name << endl; int test_img_num = feature_class.read_images_in_folder(img_name); std::cout << "測試圖個數:" << test_img_num << endl; // 訓練用的輸入和標籤 Mat testmat; testmat = cv::Mat::zeros(test_img_num, 32, CV_32F); // 遍歷圖並提取特徵 vector<Mat> test_img = feature_class.data_search(test_img_dir, test_img_namehead, test_img_type, test_img_num); for (size_t i = 0; i < test_img_num; i++) { resize(test_img[i], test_img[i], Size(test_img[i].cols / 2, test_img[i].rows / 2)); cv::namedWindow("vetmat", 0); cv::imshow("vetmat", test_img[i]);//test_img[i].clone(); // 影象分割 Mat src = test_img[i].clone(); Mat dst = Mat::zeros(test_img[i].size(), CV_8UC3); Mat edge = Mat::zeros(test_img[i].size(), CV_8UC3); Water_Cut(src, dst, edge); // 影象特徵_HU Mat hu_dst = dst.clone(); double Hu[7] = { 0 }; feature_class.feature_hu(hu_dst, Hu); // 影象特徵_COLOR Mat color_dst = dst.clone(); float Mom[9] = { 0 }; feature_class.feature_color(color_dst, Mom); // 影象特徵_GLCM Mat glcm_dst = dst.clone(); cv::cvtColor(glcm_dst, glcm_dst, CV_RGB2GRAY); float glcm_data[16] = { 0 }; feature_class.feature_glcm(glcm_dst, glcm_data); cv::waitKey(); float test_data[32] = { 0 }; for (size_t j = 0; j < 7; j++) { test_data[j] = (float)Hu[j]; } for (size_t j = 0; j < 9; j++) { test_data[7 + j] = (float)Mom[j]; } for (size_t j = 0; j < 16; j++) { test_data[16 + j] = (float)glcm_data[j]; } vector<float> testdata; // 特徵值——一類(一張圖)的特徵 for (size_t k = 0; k < 32; k++) { testdata.push_back(test_data[k]); } std::cout << "testdata size:"; std::cout << testdata.size() << endl; for (size_t j = 0; j < testdata.size(); j++) { testmat.at<float>(i, j) = testdata[j]; } } Ptr<SVM> svmtest = Algorithm::load<SVM>("svm.xml"); // SVM::load()是一個靜態函式,不能單獨用 Mat result; float temp = svmtest->predict(testmat, result); std::cout << "分類結果" << endl; std::cout << result << endl; for (size_t i = 0; i < test_img_num; i++) { int a = result.at<Point2f>(i, 0).x; std::cout << "最終分類為:" << "第" << a << "號瓷磚" << endl; } #endif system("pause"); return 0; }
子程式
#include <opencv2/opencv.hpp> #include <iostream> #include <vector> #include "time.h" using namespace cv; using namespace std; using namespace cv::ml; class Feature { public: /* 第一步:建立類 #include <opencv2/opencv.hpp> #include <iostream> #include <vector> #include "time.h" using namespace cv; using namespace std; 第二步:包含類 Feature feature_class; 第三步: 集合顏色+形狀+紋理 // 影象特徵_HU Mat hu_dst = dst.clone(); double Hu[7] = { 0 }; feature_class.feature_hu(hu_dst, Hu); // 影象特徵_COLOR Mat color_dst = dst.clone(); float Mom[9] = { 0 }; feature_class.feature_color(color_dst, Mom); // 影象特徵_GLCM Mat glcm_dst = dst.clone(); cv::cvtColor(glcm_dst, glcm_dst, CV_RGB2GRAY); float glcm_data[16] = { 0 }; feature_class.feature_glcm(glcm_dst, glcm_data); 第四步: // 特徵集合7+9+16 float test_data[32] = { 0 }; for (size_t j = 0; j < 7; j++) { test_data[j] = (float)Hu[j]; } for (size_t j = 0; j < 9; j++) { test_data[7 + j] = (float)Mom[j]; } for (size_t j = 0; j < 16; j++) { test_data[16 + j] = (float)glcm_data[j]; } */ /* 【顏色】 */ // 顏色 計算三階矩 double calc3orderMom(Mat &channel) //計算三階矩 { uchar *p; double mom = 0; double m = mean(channel)[0]; //計算單通道影象的均值 int nRows = channel.rows; int nCols = channel.cols; if (channel.isContinuous()) //連續儲存有助於提升影象掃描速度 { nCols *= nRows; nRows = 1; } for (int i = 0; i < nRows; i++) //計算立方和 { p = channel.ptr<uchar>(i); for (int j = 0; j < nCols; j++) mom += pow((p[j] - m), 3); } float temp; temp = cvCbrt((float)(mom / (nRows*nCols))); //求均值的立方根 mom = (double)temp; return mom; } // 顏色 計算9個顏色矩:3個通道的1、2、3階矩 double *colorMom(Mat &img) { double *Mom = new double[9]; //存放9個顏色矩 if (img.channels() != 3) std::cout << "Error,input image must be a color image" << endl; Mat b(img.rows, img.cols, CV_8U); Mat r(img.rows, img.cols, CV_8U); Mat g(img.rows, img.cols, CV_8U); Mat channels[] = { b, g, r }; split(img, channels); //cv::imshow("r", channels[0]); //cv::imshow("g", channels[1]); //cv::imshow("b", channels[2]); //waitKey(0); Mat tmp_m, tmp_sd; //計算b通道的顏色矩 meanStdDev(b, tmp_m, tmp_sd); Mom[0] = tmp_m.at<double>(0, 0); Mom[3] = tmp_sd.at<double>(0, 0); Mom[6] = calc3orderMom(b); // cout << Mom[0] << " " << Mom[1] << " " << Mom[2] << " " << endl; //計算g通道的顏色矩 meanStdDev(g, tmp_m, tmp_sd); Mom[1] = tmp_m.at<double>(0, 0); Mom[4] = tmp_sd.at<double>(0, 0); Mom[7] = calc3orderMom(g); // cout << Mom[3] << " " << Mom[4] << " " << Mom[5] << " " << endl; //計算r通道的顏色矩 meanStdDev(r, tmp_m, tmp_sd); Mom[2] = tmp_m.at<double>(0, 0); Mom[5] = tmp_sd.at<double>(0, 0); Mom[8] = calc3orderMom(r); // cout << Mom[6] << " " << Mom[7] << " " << Mom[8] << " " << endl; return Mom;//返回顏色矩陣列 } // 顏色 bool feature_color(Mat src, float Mom[9]) { if (src.channels() == 3) { // 影象特徵_COLOR Mat color_dst = src.clone(); cv::cvtColor(color_dst, color_dst, CV_RGB2HSV); double *MOM; MOM = colorMom(color_dst); for (int i = 0; i < 9; i++) { std::cout << (float)MOM[i] << endl; Mom[i] = (float)MOM[i]; } return true; } else { std::cout << "channels!=3"; return false; } } /* 【形狀】 */ bool feature_hu(Mat src, double Hu[7]) { if (src.channels() == 3) { // 影象特徵_HU Mat hu_dst = src.clone(); cv::cvtColor(hu_dst, hu_dst, CV_RGB2GRAY); Canny(hu_dst, hu_dst, 0, 120); //double Hu[7]; //儲存得到的Hu矩陣 Moments mo = moments(hu_dst);//矩變數 HuMoments(mo, Hu); for (int i = 0; i < 7; i++) { std::cout << (float)Hu[i] << endl; } return true; } else if ((src.channels() == 1)) { Mat hu_dst = src.clone(); Canny(hu_dst, hu_dst, 0, 120); //double Hu[7]; //儲存得到的Hu矩陣 Moments mo = moments(hu_dst);//矩變數 HuMoments(mo, Hu); for (int i = 0; i < 7; i++) { std::cout << (float)Hu[i] << endl; } return true; } else { return false; } } // 紋理 const int gray_level = 16;//紋理區域塊的大小,通常將影象劃分成若干個紋理塊計算 vector<double> glamvalue;//全域性變數 //【】第一步:j計算共生矩陣 void getglcm_0(Mat& input, Mat& dst)//0度灰度共生矩陣 { Mat src = input; CV_Assert(1 == src.channels()); src.convertTo(src, CV_32S); int height = src.rows; int width = src.cols; int max_gray_level = 0; for (int j = 0; j < height; j++)//尋找畫素灰度最大值 { int* srcdata = src.ptr<int>(j); for (int i = 0; i < width; i++) { if (srcdata[i] > max_gray_level) { max_gray_level = srcdata[i]; } } } max_gray_level++;//畫素灰度最大值加1即為該矩陣所擁有的灰度級數 if (max_gray_level > 16)//若灰度級數大於16,則將影象的灰度級縮小至16級,減小灰度共生矩陣的大小。 { for (int i = 0; i < height; i++) { int*srcdata = src.ptr<int>(i); for (int j = 0; j < width; j++) { srcdata[j] = (int)srcdata[j] / gray_level; } } dst.create(gray_level, gray_level, CV_32SC1); dst = Scalar::all(0); for (int i = 0; i < height; i++) { int*srcdata = src.ptr<int>(i); for (int j = 0; j < width - 1; j++) { int rows = srcdata[j]; int cols = srcdata[j + 1]; dst.ptr<int>(rows)[cols]++; } } } else//若灰度級數小於16,則生成相應的灰度共生矩陣 { dst.create(max_gray_level, max_gray_level, CV_32SC1); dst = Scalar::all(0); for (int i = 0; i < height; i++) { int*srcdata = src.ptr<int>(i); for (int j = 0; j < width - 1; j++) { int rows = srcdata[j]; int cols = srcdata[j + 1]; dst.ptr<int>(rows)[cols]++; } } } } void getglcm_45(Mat& input, Mat& dst)//45度灰度共生矩陣 { Mat src = input; CV_Assert(1 == src.channels()); src.convertTo(src, CV_32S); int height = src.rows; int width = src.cols; int max_gray_level = 0; for (int j = 0; j < height; j++) { int* srcdata = src.ptr<int>(j); for (int i = 0; i < width; i++) { if (srcdata[i] > max_gray_level) { max_gray_level = srcdata[i]; } } } max_gray_level++; if (max_gray_level > 16) { for (int i = 0; i < height; i++)//將影象的灰度級縮小至16級,減小灰度共生矩陣的大小。 { int*srcdata = src.ptr<int>(i); for (int j = 0; j < width; j++) { srcdata[j] = (int)srcdata[j] / gray_level; } } dst.create(gray_level, gray_level, CV_32SC1); dst = Scalar::all(0); for (int i = 0; i < height - 1; i++) { int*srcdata = src.ptr<int>(i); int*srcdata1 = src.ptr<int>(i + 1); for (int j = 0; j < width - 1; j++) { int rows = srcdata[j]; int cols = srcdata1[j + 1]; dst.ptr<int>(rows)[cols]++; } } } else { dst.create(max_gray_level, max_gray_level, CV_32SC1); dst = Scalar::all(0); for (int i = 0; i < height - 1; i++) { int*srcdata = src.ptr<int>(i); int*srcdata1 = src.ptr<int>(i + 1); for (int j = 0; j < width - 1; j++) { int rows = srcdata[j]; int cols = srcdata1[j + 1]; dst.ptr<int>(rows)[cols]++; } } } } void getglcm_90(Mat& input, Mat& dst)//90度灰度共生矩陣 { Mat src = input; CV_Assert(1 == src.channels()); src.convertTo(src, CV_32S); int height = src.rows; int width = src.cols; int max_gray_level = 0; for (int j = 0; j < height; j++) { int* srcdata = src.ptr<int>(j); for (int i = 0; i < width; i++) { if (srcdata[i] > max_gray_level) { max_gray_level = srcdata[i]; } } } max_gray_level++; if (max_gray_level > 16) { for (int i = 0; i < height; i++)//將影象的灰度級縮小至16級,減小灰度共生矩陣的大小。 { int*srcdata = src.ptr<int>(i); for (int j = 0; j < width; j++) { srcdata[j] = (int)srcdata[j] / gray_level; } } dst.create(gray_level, gray_level, CV_32SC1); dst = Scalar::all(0); for (int i = 0; i < height - 1; i++) { int*srcdata = src.ptr<int>(i); int*srcdata1 = src.ptr<int>(i + 1); for (int j = 0; j < width; j++) { int rows = srcdata[j]; int cols = srcdata1[j]; dst.ptr<int>(rows)[cols]++; } } } else { dst.create(max_gray_level, max_gray_level, CV_32SC1); dst = Scalar::all(0); for (int i = 0; i < height - 1; i++) { int*srcdata = src.ptr<int>(i); int*srcdata1 = src.ptr<int>(i + 1); for (int j = 0; j < width; j++) { int rows = srcdata[j]; int cols = srcdata1[j]; dst.ptr<int>(rows)[cols]++; } } } } void getglcm_135(Mat& input, Mat& dst)//135度灰度共生矩陣 { Mat src = input; CV_Assert(1 == src.channels()); src.convertTo(src, CV_32S); int height = src.rows; int width = src.cols; int max_gray_level = 0; for (int j = 0; j < height; j++) { int* srcdata = src.ptr<int>(j); for (int i = 0; i < width; i++) { if (srcdata[i] > max_gray_level) { max_gray_level = srcdata[i]; } } } max_gray_level++; if (max_gray_level > 16) { for (int i = 0; i < height; i++)//將影象的灰度級縮小至16級,減小灰度共生矩陣的大小。 { int*srcdata = src.ptr<int>(i); for (int j = 0; j < width; j++) { srcdata[j] = (int)srcdata[j] / gray_level; } } dst.create(gray_level, gray_level, CV_32SC1); dst = Scalar::all(0); for (int i = 0; i < height - 1; i++) { int*srcdata = src.ptr<int>(i); int*srcdata1 = src.ptr<int>(i + 1); for (int j = 1; j < width; j++) { int rows = srcdata[j]; int cols = srcdata1[j - 1]; dst.ptr<int>(rows)[cols]++; } } } else { dst.create(max_gray_level, max_gray_level, CV_32SC1); dst = Scalar::all(0); for (int i = 0; i < height - 1; i++) { int*srcdata = src.ptr<int>(i); int*srcdata1 = src.ptr<int>(i + 1); for (int j = 1; j < width; j++) { int rows = srcdata[j]; int cols = srcdata1[j - 1]; dst.ptr<int>(rows)[cols]++; } } } } // 【】第二步:計算紋理特徵 // 特徵值計算—— double& Asm, double& Con, double& Ent, double& Idm void feature_computer(Mat&src, float& Asm, float& Con, float& Ent, float& Idm)//計算特徵值 { int height = src.rows; int width = src.cols; int total = 0; for (int i = 0; i < height; i++) { int*srcdata = src.ptr<int>(i); for (int j = 0; j < width; j++) { total += srcdata[j];//求影象所有畫素的灰度值的和 } } Mat copy; copy.create(height, width, CV_64FC1); for (int i = 0; i < height; i++) { int*srcdata = src.ptr<int>(i); float*copydata = copy.ptr<float>(i); for (int j = 0; j < width; j++) { copydata[j] = (float)srcdata[j] / (float)total;//影象每一個畫素的的值除以畫素總和 } } for (int i = 0; i < height; i++) { float*srcdata = copy.ptr<float>(i); for (int j = 0; j < width; j++) { Asm += srcdata[j] * srcdata[j]; //能量 if (srcdata[j]>0) { Ent -= srcdata[j] * log(srcdata[j]); //熵 } Con += (float)(i - j)*(float)(i - j)*srcdata[j]; //對比度 Idm += srcdata[j] / (1 + (float)(i - j)*(float)(i - j)); //逆差矩 } } } // 【】融合第一、二步 /* Mat src_gray; float data[16] = {0}; */ void feature_glcm(Mat src_gray, float data[16]) { Mat dst_0, dst_90, dst_45, dst_135; getglcm_0(src_gray, dst_0); float asm_0 = 0, con_0 = 0, ent_0 = 0, idm_0 = 0; feature_computer(dst_0, asm_0, con_0, ent_0, idm_0); getglcm_45(src_gray, dst_45); float asm_45 = 0, con_45 = 0, ent_45 = 0, idm_45 = 0; feature_computer(dst_45, asm_45, con_45, ent_45, idm_45); getglcm_90(src_gray, dst_90); float asm_90 = 0, con_90 = 0, ent_90 = 0, idm_90 = 0; feature_computer(dst_90, asm_90, con_90, ent_90, idm_90); getglcm_135(src_gray, dst_135); float asm_135 = 0, con_135 = 0, ent_135 = 0, idm_135 = 0; feature_computer(dst_135, asm_135, con_135, ent_135, idm_135); float AMS[4] = { asm_0, asm_45, asm_90, asm_135 }; float COM[4] = { con_0, con_45, con_90, con_135 }; float ENT[4] = { ent_0, ent_45, ent_90, ent_135 }; float IDM[4] = { idm_0, idm_45, idm_90, idm_135 }; float glcm_data[16] = { asm_0, asm_45, asm_90, asm_135, con_0, con_45, con_90, con_135, ent_0, ent_45, ent_90, ent_135, idm_0, idm_45, idm_90, idm_135 }; /*std::cout << "特徵資料:" << endl;*/ for (size_t i = 0; i < 16; i++) { data[i] = glcm_data[i]; //std::cout << data[i] << " "; } } // 讀取當前資料夾圖片的個數子程式 /* cv::String pattern = "./save/*.bmp"; int cout = read_images_in_folder(pattern); */ size_t read_images_in_folder(cv::String pattern)//讀取當前指定目錄的圖片的個數 { vector<cv::String> fn; glob(pattern, fn, false);//OpenCV自帶一個函式glob()可以遍歷檔案 size_t count = fn.size(); //number of png files in images folder return count; } // 【】檔案檢索 /* string train_img_dir = "C:\\Users\\Administrator\\Desktop\\樣品\\訓練"; string train_img_namehead = "test"; string train_img_type = "bmp"; size_t train_img_num = 4; vector<Mat> train_img = data_search(train_img_dir, train_img_namehead, train_img_type, train_img_num); for (size_t i = 0; i < train_img_num; i++) { namedWindow("vetmat", 0); imshow("vetmat", train_img[i]); waitKey(0); } */ vector<Mat> data_search(string &img_dir, string &img_namehead, string &img_type, size_t n) { float train_data[4][16] = { 0 }; vector<Mat> src; for (int i = 0; i < n; i++) { string pos; stringstream ss; ss << i; ss >> pos; string img_name = img_dir + "\\" + img_namehead + pos + "." + img_type; //cout << img_name << endl; Mat outsrc = imread(img_name); src.push_back(outsrc); } return src; } private: };
子函式
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; /*遺留問題:兩點的確立*/ void Water_Cut(InputArray& src, OutputArray& dst, OutputArray& edge) { Mat srcImage; src.copyTo(srcImage); //cv::resize(srcImage, srcImage, Size(srcImage.cols / 2, srcImage.rows / 2)); cv::namedWindow("resImage", 0); cv::imshow("resImage", srcImage); //waitKey(); // 【mask兩點】 //mask的第一點 maskImage Mat maskImage; maskImage = Mat(srcImage.size(), CV_8UC1); // 掩模,在上面做標記,然後傳給findContours maskImage = Scalar::all(0); Point point1(0, 0), point2(100, 10); //line(maskImage, point1, point2, Scalar::all(255), 5, 8, 0); circle(maskImage, point1, 10, Scalar::all(255), 100); //mask的第二點 maskImage Point point3(srcImage.cols / 2, srcImage.rows / 2), point4(srcImage.cols / 2+200, srcImage.rows / 2); //line(maskImage, point3, point4, Scalar::all(255), 5, 8, 0); circle(maskImage, point3, 10, Scalar::all(255), 100); /*namedWindow("resImage", 0); imshow("resImage", maskImage); waitKey();*/ // 【輪廓】 vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(maskImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE); // 【分水嶺】 // 引數二:maskWaterShed(CV_32S) Mat maskWaterShed; // watershed()函式的引數 maskWaterShed = Mat(maskImage.size(), CV_32S);//空白掩碼 maskWaterShed maskWaterShed = Scalar::all(0); /* 在maskWaterShed上繪製輪廓 */ for (int index = 0; index < contours.size(); index++) drawContours(maskWaterShed, contours, index, Scalar::all(index + 1), -1, 8, hierarchy, INT_MAX); /* 如果imshow這個maskWaterShed,我們會發現它是一片黑,原因是在上面我們只給它賦了1,2,3這樣的值,通過程式碼80行的處理我們才能清楚的看出結果 */ // 引數一:srcImage(CV_8UC3) watershed(srcImage, maskWaterShed); //int index = maskWaterShed.at<int>(row, col);操作 // 【隨機生成幾種顏色】 vector<Vec3b> colorTab; for (int i = 0; i < contours.size(); i++) { int b = theRNG().uniform(0, 255); int g = theRNG().uniform(0, 255); int r = theRNG().uniform(0, 255); colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r)); } Mat dst_ = Mat::zeros(maskWaterShed.size(), CV_8UC3); Mat dst_edge = Mat::zeros(maskWaterShed.size(), CV_8UC3); int index = maskWaterShed.at<int>(maskWaterShed.rows / 2, maskWaterShed.cols / 2); int index_temp = 0; for (int i = 0; i < maskWaterShed.rows; i++) { for (int j = 0; j < maskWaterShed.cols; j++) { index_temp = maskWaterShed.at<int>(i, j); //cout << index_temp << endl; if (index_temp == index)//取中心的標籤區域 { dst_edge.at<Vec3b>(i, j) = Vec3b((uchar)255, (uchar)255, (uchar)255); //colorTab[index - 1]; dst_.at<Vec3b>(i, j) = srcImage.at<Vec3b>(i, j); } } } cv::namedWindow("分割結果", 0); cv::imshow("分割結果", dst_); imwrite("條紋1.bmp", dst_); /*Mat dst_add; addWeighted(dst_edge, 0.3, srcImage, 0.7, 0, dst_add); namedWindow("加權結果", 0); imshow("加權結果", dst_add);*/ cv::namedWindow("連通域", 0); cv::imshow("連通域", dst_edge); imwrite("條紋1_.bmp", dst_edge); dst_.copyTo(dst); dst_edge.copyTo(edge); }