Erode and dilate image with opencv's Morphological filters
#include <opencv2/highgui/highgui.hpp> #include <opencv2/core/core.hpp> #include <vector> #include <iostream> #include <opencv2/imgproc/imgproc.hpp> //#include "../../../../../Downloads/colourhistogram.h" using namespace cv; using namespace std; int main() { Mat image = imread("D:\\images\\church01.jpg"); if (!image.data) { cout<<"cannot be opened"<<endl; return -1; } namedWindow("original image",CV_WINDOW_AUTOSIZE); imshow("original image",image); cvtColor(image,image,CV_RGB2GRAY); Mat eroded; erode(image,eroded,Mat(),Point(-1,-1),3); //display eroded image namedWindow("Eroded image",CV_WINDOW_AUTOSIZE); imshow("Eroded image",eroded); //dilate the image Mat dilated; dilate(image,dilated,Mat()); namedWindow("Dilated Image",CV_WINDOW_AUTOSIZE); imshow("Dilated Image",dilated); waitKey(0); system("pause"); return 0; }
可以利用morphologyEx函数来得到higher-level的image
Mat elements5(5,5,CV_8U,Scalar(1)); Mat closed; morphologyEx(image,closed,MORPH_CLOSE,elements5); namedWindow("morphologyEx_close",CV_WINDOW_AUTOSIZE); imshow("morphologyEx_close",closed); Mat opened; morphologyEx(image,opened,MORPH_OPEN,elements5); namedWindow("morphologyEx_open",CV_WINDOW_AUTOSIZE); imshow("morphologyEx_open",opened);
Detecting edges amd corners using morphological filters
#include <opencv2/highgui/highgui.hpp> #include <opencv2/core/core.hpp> #include <vector> #include <iostream> #include <opencv2/imgproc/imgproc.hpp> #include "../../../../../Downloads/colourhistogram.h" using namespace cv; using namespace std; class MorphoFeatures { private: int threshold;//threshold to produce binary image Mat cross;//structing elements used in corner detection Mat diamond; Mat square; Mat x; public: void applyThreshold(Mat &result) { //apply threshold on result if (threshold>0) cv::threshold(result,result,threshold,255,THRESH_BINARY); } Mat getEdges(const Mat &image) { //get the gradient image Mat result_image; morphologyEx(image,result_image,MORPH_GRADIENT,Mat()); applyThreshold(result_image); return result_image; } }; int main() { Mat image = imread("D:\\images\\building.jpg"); namedWindow("original_image",CV_WINDOW_AUTOSIZE); imshow("original_image",image); MorphoFeatures morph; //morph.setThreshold(40); Mat edges; edges = morph.getEdges(image); namedWindow("edge_image",CV_WINDOW_AUTOSIZE); imshow("edge_image",edges); waitKey(0); system("pause"); return 0; }
Segmenting images using watersheds
#include <opencv2/highgui/highgui.hpp> #include <opencv2/core/core.hpp> #include <vector> #include <iostream> #include <opencv2/imgproc/imgproc.hpp> //#include "../../../../../Downloads/colourhistogram.h" using namespace std; //class WatershedSegmenter { // //private: // // cv::Mat markers; // //public: // // void setMarkers(const cv::Mat& markerImage) { // // // Convert to image of ints // markerImage.convertTo(markers,CV_32S); // } // // cv::Mat process(const cv::Mat &image) { // // // Apply watershed // cv::watershed(image,markers); // // return markers; // } // // // Return result in the form of an image // cv::Mat getSegmentation() { // // cv::Mat tmp; // // all segment with label higher than 255 // // will be assigned value 255 // markers.convertTo(tmp,CV_8U); // // return tmp; // } // // // Return watershed in the form of an image // cv::Mat getWatersheds() { // // cv::Mat tmp; // markers.convertTo(tmp,CV_8U,255,255); // // return tmp; // } //}; //int main() //{ // // Read input image // cv::Mat image= cv::imread("D:\\images\\rain.jpg"); // if (!image.data) // return 0; // // // Display the image // cv::namedWindow("Original Image"); // cv::imshow("Original Image",image); // // // Get the binary map // cv::Mat binary; // binary= cv::imread("D:\\images\\binary.bmp"); // // // Display the binary image // cv::namedWindow("Binary Image"); // cv::imshow("Binary Image",binary); // // // Eliminate noise and smaller objects // cv::Mat fg; // cv::erode(binary,fg,cv::Mat(),cv::Point(-1,-1),6); // // // Display the foreground image // cv::namedWindow("Foreground Image"); // cv::imshow("Foreground Image",fg); // // // Identify image pixels without objects // cv::Mat bg; // cv::dilate(binary,bg,cv::Mat(),cv::Point(-1,-1),6); // cv::threshold(bg,bg,1,128,cv::THRESH_BINARY_INV); // // // Display the background image // cv::namedWindow("Background Image"); // cv::imshow("Background Image",bg); // // // Show markers image // cv::Mat markers(binary.size(),CV_8U,cv::Scalar(0)); // markers= fg+bg; // cv::namedWindow("Markers"); // cv::imshow("Markers",markers); // // // Create watershed segmentation object // //WatershedSegmenter segmenter; // // //// Set markers and process // //segmenter.setMarkers(markers); // //segmenter.process(image); // // //// Display segmentation result // //cv::namedWindow("Segmentation",CV_WINDOW_AUTOSIZE); // //cv::imshow("Segmentation",segmenter.getSegmentation()); // // // Display watersheds // /*cv::namedWindow("Watersheds"); // cv::imshow("Watersheds",segmenter.getWatersheds());*/ // // // Open another image // image= cv::imread("D:\\images\\tower.jpg"); // // // Identify background pixels // cv::Mat imageMask(image.size(),CV_8U,cv::Scalar(0)); // cv::rectangle(imageMask,cv::Point(5,5),cv::Point(image.cols-5,image.rows-5),cv::Scalar(255),3); // // Identify foreground pixels (in the middle of the image) // cv::rectangle(imageMask,cv::Point(image.cols/2-10,image.rows/2-10), // cv::Point(image.cols/2+10,image.rows/2+10),cv::Scalar(1),10); // // // Set markers and process // segmenter.setMarkers(imageMask); // segmenter.process(image); // // // Display the image with markers // cv::rectangle(image,cv::Point(5,5),cv::Point(image.cols-5,image.rows-5),cv::Scalar(255,255,255),3); // cv::rectangle(image,cv::Point(image.cols/2-10,image.rows/2-10), // cv::Point(image.cols/2+10,image.rows/2+10),cv::Scalar(1,1,1),10); // cv::namedWindow("Image with marker"); // cv::imshow("Image with marker",image); // // // Display watersheds // cv::namedWindow("Watersheds of foreground object"); // cv::imshow("Watersheds of foreground object",segmenter.getWatersheds()); // // // Open another image // image= cv::imread("D:\\images\\tower.jpg"); // // // define bounding rectangle // cv::Rect rectangle(50,70,image.cols-150,image.rows-180); // // cv::Mat result; // segmentation result (4 possible values) // cv::Mat bgModel,fgModel; // the models (internally used) // // GrabCut segmentation // cv::grabCut(image, // input image // result, // segmentation result // rectangle,// rectangle containing foreground // bgModel,fgModel, // models // 1, // number of iterations // cv::GC_INIT_WITH_RECT); // use rectangle // // // Get the pixels marked as likely foreground // cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ); // // Generate output image // cv::Mat foreground(image.size(),CV_8UC3,cv::Scalar(255,255,255)); // image.copyTo(foreground,result); // bg pixels not copied // // // draw rectangle on original image // cv::rectangle(image, rectangle, cv::Scalar(255,255,255),1); // cv::namedWindow("Image"); // cv::imshow("Image",image); // // // display result // cv::namedWindow("Segmented Image"); // cv::imshow("Segmented Image",foreground); // // // Open another image // image= cv::imread("D:\\images\\rain.jpg"); // // // define bounding rectangle // cv::Rect rectangle2(10,100,380,180); // // cv::Mat bkgModel,fgrModel; // the models (internally used) // // GrabCut segmentation // cv::grabCut(image, // input image // result, // segmentation result // rectangle2,bkgModel,fgrModel,5,cv::GC_INIT_WITH_RECT); // // Get the pixels marked as likely foreground // // cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ); // result= result&1; // foreground.create(image.size(),CV_8UC3); // foreground.setTo(cv::Scalar(255,255,255)); // image.copyTo(foreground,result); // bg pixels not copied // // // draw rectangle on original image // cv::rectangle(image, rectangle2, cv::Scalar(255,255,255),1); // cv::namedWindow("Image 2"); // cv::imshow("Image 2",image); // // // display result // cv::namedWindow("Foreground objects"); // cv::imshow("Foreground objects",foreground); // // cv::waitKey(); // system("pause"); // return 0; //} // // class WatershedSegmenter{ private: cv::Mat markers; public: void setMarkers(const cv::Mat& markerImage){ markerImage.convertTo(markers, CV_32S); } cv::Mat process(const cv::Mat &image){ cv::watershed(image,markers); return markers; } }; int main () { using namespace cv; cv::Mat image = cv::imread("D:\\images\\waves.jpg"); cv::Mat binary;// = cv::imread(argv[2], 0); cv::cvtColor(image, binary, CV_BGR2GRAY); cv::threshold(binary, binary, 100, 255, THRESH_BINARY); imshow("original_image", image); imshow("original_binary", binary); // Eliminate noise and smaller objects cv::Mat fg; cv::erode(binary,fg,cv::Mat(),cv::Point(-1,-1),2); imshow("fg", fg); // Identify image pixels without objects cv::Mat bg; cv::dilate(binary,bg,cv::Mat(),cv::Point(-1,-1),3); cv::threshold(bg,bg,1, 128,cv::THRESH_BINARY_INV); imshow("bg", bg); // Create markers image cv::Mat markers(binary.size(),CV_8U,cv::Scalar(0)); markers= fg+bg; imshow("markers", markers); // Create watershed segmentation object WatershedSegmenter segmenter; segmenter.setMarkers(markers); cv::Mat result = segmenter.process(image); result.convertTo(result,CV_8U); imshow("final_result", result); waitKey(0); system("pause"); return 0; }