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;
}