Morfologia matematyczna
Dylacja z kwadratowym elementem strukturalnym
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main(){ Mat dilated_img; Mat img = imread("./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); for(int i = 1; i<10; i++){ Mat structuring_element(2*i+1, 2*i+1, CV_8U, Scalar(1) ); dilate( img, dilated_img, structuring_element ); imshow( "Dilate", dilated_img ); } waitKey(0); return 0; }
Dylacja z krzyżowym elementem strukturalnym
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main(){ Mat dilated_img; Mat img = imread("./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); for(int i = 1; i<10; i++){ Mat element = getStructuringElement( MORPH_CROSS, Size( 2*i + 1, 2*i+1 ), Point( i, i) ); dilate( img, dilated_img, element ); imshow( "Dilate", dilated_img ); } waitKey(0); return 0; }
Dylacja z kołowym elementem strukturalnym
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main(){ Mat dilated_img; Mat img = imread("./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); for(int i = 1; i<10; i++){ Mat element = getStructuringElement( MORPH_ELLIPSE, Size( 2*i + 1, 2*i+1 ), Point( i, i) ); dilate( img, dilated_img, element ); imshow( "Dilate", dilated_img ); } waitKey(0); return 0; }
Dylacja z eliptycznym elementem strukturalnym
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main(){ Mat dilated_img; Mat img = imread("./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); for(int i = 1; i<10; i++){ Mat element = getStructuringElement( MORPH_ELLIPSE, Size( 2*i + 1, 4*i+1 ), Point( i, i) ); dilate( img, dilated_img, element ); imshow( "Dilate", dilated_img ); } waitKey(0); return 0; }
Dylacja z róznymi elmentami strukturalnymi
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; Mat img; int dilation_elem = 0; int dilation_size = 0; int const max_elem = 2; int const max_kernel_size = 21; void dil(int, void* ); int main(){ /// Read the image img = imread( "./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); /// Create Trackbar to enter the number of bins namedWindow( "Source image", CV_WINDOW_AUTOSIZE ); createTrackbar( "Element:", "Source image", &dilation_elem, max_elem, dil ); createTrackbar( "Kernel size:", "Source image", &dilation_size, max_kernel_size, dil ); dil(0,0); waitKey(0); return 0; } void dil(int, void* ){ Mat dilated_img; int dilation_type; if( dilation_elem == 0 ){ dilation_type = MORPH_RECT; } else if( dilation_elem == 1 ){ dilation_type = MORPH_CROSS; } else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; } Mat element = getStructuringElement( dilation_type, Size( 2*dilation_size + 1, 10+2*dilation_size+1 ), Point( dilation_size, dilation_size ) ); dilate( img, dilated_img, element ); imshow( "Source image", dilated_img ); }
Dylacja z włsnym elementem strukturalnym
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; Mat circle(double r); int main(){ Mat dilated_img; Mat img = imread("./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); Mat structuring_element = circle((double) 5); cout<< structuring_element << endl; dilate( img, dilated_img, structuring_element ); imshow( "Binary", dilated_img ); waitKey(0); return 0; } Mat circle(double r){ Mat structuring_element( 2*r+1, 2*r+1, CV_8U, Scalar(1) ); for(double i = 0 ; i < 2*r+1 ; i+=1){ for(double j = 0 ; j < 2*r+1 ; j+=1){ if(pow(i-r,2)+pow(j-r,2) > pow(r,2)){ structuring_element.at<uchar>((int)i,(int)j)= 0; } } } return structuring_element; }
Erozja z kwadratowym elementem strukturalnym
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main(){ Mat erode_img; Mat img = imread("./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); for(int i = 1; i<10; i++){ Mat structuring_element(2*i+1, 2*i+1, CV_8U, Scalar(1) ); erode( img, erode_img, structuring_element ); imshow( "Erode", erode_img ); } waitKey(0); return 0; }
Dylacja z krzyżowym elementem strukturalnym
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main(){ Mat erode_img; Mat img = imread("./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); for(int i = 1; i<10; i++){ Mat element = getStructuringElement( MORPH_CROSS, Size( 2*i + 1, 2*i+1 ), Point( i, i) ); erode( img, erode_img, element ); imshow( "Dilate", erode_img ); } waitKey(0); return 0; }
Dylacja z kołowym elementem strukturalnym
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main(){ Mat erode_img; Mat img = imread("./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); for(int i = 1; i<10; i++){ Mat element = getStructuringElement( MORPH_ELLIPSE, Size( 2*i + 1, 2*i+1 ), Point( i, i) ); erode( img, erode_img, element ); imshow( "Dilate", erode_img ); } waitKey(0); return 0; }
Dylacja z różnymi elementami strukturalnymi
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; Mat img; int erode_elem = 0; int erode_size = 0; int const max_elem = 2; int const max_kernel_size = 21; void erod(int, void* ); int main(){ /// Read the image img = imread( "/home/przemek/Pulpit/openCVExamples/ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); /// Create Trackbar to enter the number of bins namedWindow( "Source image", CV_WINDOW_AUTOSIZE ); createTrackbar( "Element:", "Source image", &erode_elem, max_elem, erod ); createTrackbar( "Kernel size:", "Source image", &erode_size, max_kernel_size, erod ); erod(0,0); waitKey(0); return 0; } void erod(int, void* ){ Mat erode_img; int erode_type; if( erode_elem == 0 ){ erode_type = MORPH_RECT; } else if( erode_elem == 1 ){ erode_type = MORPH_CROSS; } else if( erode_elem == 2) { erode_type = MORPH_ELLIPSE; } Mat element = getStructuringElement( erode_type, Size( 2*erode_size + 1, 10+2*erode_size+1 ), Point( erode_size, erode_size ) ); erode( img, erode_img, element ); imshow( "Source image", erode_img ); }
Operacja otwarcia
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main(){ Mat opened_img; Mat img = imread("./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); Mat structuring_element( 5, 5, CV_8U, Scalar(1) ); morphologyEx( img, opened_img, MORPH_OPEN, structuring_element ); imshow( "Opene", opened_img ); waitKey(0); return 0; }
Operacja zamknięcia
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main(){ Mat closed_img; Mat img = imread("./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); Mat structuring_element( 5, 5, CV_8U, Scalar(1) ); morphologyEx( img, closed_img, MORPH_CLOSE, structuring_element ); imshow( "Close", closed_img ); waitKey(0); return 0; }
Operacja otwarcia z różnymi elementami strukturalnymi
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; Mat img; int opened_elem = 0; int opened_size = 0; int const max_elem = 2; int const max_kernel_size = 41; void open(int, void* ); int main(){ /// Read the image img = imread( "./ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); /// Create Trackbar to enter the number of bins namedWindow( "Source image", CV_WINDOW_AUTOSIZE ); createTrackbar( "Element:", "Source image", &opened_elem, max_elem, open ); createTrackbar( "Kernel size:", "Source image", &opened_size, max_kernel_size, open ); open(0,0); waitKey(0); return 0; } void open(int, void* ){ Mat opened_img; int opened_type; if( opened_elem == 0 ){ opened_type = MORPH_RECT; } else if( opened_elem == 1 ){ opened_type = MORPH_CROSS; } else if( opened_elem == 2) { opened_type = MORPH_ELLIPSE; } Mat element = getStructuringElement( opened_type, Size( 2*opened_size + 1, 10+2*opened_size+1 ), Point( opened_size, opened_size ) ); morphologyEx( img, opened_img, MORPH_OPEN, element ); imshow( "Source image", opened_img ); }
Operacja zamknięcia z różnymi elementami strukturalnymi
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; Mat img; int closed_elem = 0; int closed_size = 0; int const max_elem = 2; int const max_kernel_size = 51; void close(int, void* ); int main(){ /// Read the image img = imread( "/home/przemek/Pulpit/openCVExamples/ship.jpg", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 255, 255,THRESH_BINARY |THRESH_OTSU ); /// Create Trackbar to enter the number of bins namedWindow( "Source image", CV_WINDOW_AUTOSIZE ); createTrackbar( "Element:", "Source image", &closed_elem, max_elem, close ); createTrackbar( "Kernel size:", "Source image", &closed_size, max_kernel_size, close ); close(0,0); waitKey(0); return 0; } void close(int, void* ){ Mat closed_img; int closed_type; if( closed_elem == 0 ){ closed_type = MORPH_RECT; } else if( closed_elem == 1 ){ closed_type = MORPH_CROSS; } else if( closed_elem == 2) { closed_type = MORPH_ELLIPSE; } Mat element = getStructuringElement( closed_type, Size( 2*closed_size + 1, 10+2*closed_size+1 ), Point( closed_size, closed_size ) ); morphologyEx( img, closed_img, MORPH_CLOSE, element ); imshow( "Source image", closed_img ); }
Znajdowanie rogów za pomocą metody „Hit-or-Miss”.
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include #include using namespace std; using namespace cv; void hitmiss(Mat& img, Mat& dst, Mat& kernel); int main(){ Mat img_dst; Mat img_dst_1; Mat img_dst_2; Mat img_dst_3; Mat img_dst_4; Mat img = imread("./template1.png", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 100, 255,THRESH_BINARY); Mat kernel_1 = (cv::Mat_(3,3) << 0, 1, 0, -1, 1, 1, -1, -1, 0); hitmiss(img, img_dst_1, kernel_1); Mat kernel_2 = (cv::Mat_(3,3) << 0, 1, 0, 1, 1, -1, 0, -1, -1); hitmiss(img, img_dst_2, kernel_2); Mat kernel_3 = (cv::Mat_(3,3) << 0, -1, -1, 1, 1, -1, 0, 1, 0); hitmiss(img, img_dst_3, kernel_3); Mat kernel_4 = (cv::Mat_(3,3) << -1, -1, 0, -1, 1, 1, 0, 1, 0); hitmiss(img, img_dst_4, kernel_4); imshow( "Binary", img ); imshow( "Hit or Mis 1", img_dst_1 ); imshow( "Hit or Mis 2", img_dst_2 ); imshow( "Hit or Mis 3", img_dst_3 ); imshow( "Hit or Mis 4", img_dst_4 ); imshow( "Hit or Mis", img_dst_1|img_dst_2|img_dst_3|img_dst_4 ); waitKey(0); return 0; } /** * Hit-or-miss transform function * * Parameters: * img The source image, 8 bit single-channel matrix * dst The destination image * kernel The kernel matrix. 1=foreground, -1=background, 0=don't care */ void hitmiss(cv::Mat& img, cv::Mat& dst, cv::Mat& kernel) { CV_Assert(img.type() == CV_8U && img.channels() == 1); Mat img_copy; cv::Mat k1 = (kernel == 1) / 255; cv::Mat k2 = (kernel == -1) / 255; cv::normalize(img, img_copy, 0, 1, cv::NORM_MINMAX); cv::Mat e1, e2; cv::Mat ee1, ee2; cv::erode(img_copy, e1, k1); cv::erode(1-img_copy, e2, k2); dst = e1 & e2; cv::normalize(dst, dst, 0, 255, cv::NORM_MINMAX); }
Pocienianie za pomocą metody „Hit-or-Miss”.
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> void hitmiss(Mat& img, Mat& dst, Mat& kernel); int main(){ Mat img = imread("./template1.png", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 100, 255,THRESH_BINARY); Mat img_dst = img.clone(); Mat countdition; Mat prev; Mat img_temp; Mat kernel_1_1 = (Mat_(3,3) << -1, -1, -1, 0, 1, 0, 1, 1, 1); Mat kernel_1_2 = (Mat_(3,3) << 1, 0, -1, 1, 1, -1, 1, 0, -1); Mat kernel_1_3 = (Mat_(3,3) << 1, 1, 1, 0, 1, -1, -1, -1, -1); Mat kernel_1_4 = (Mat_(3,3) << -1, 0, 1, -1, 1, 1, -1, -1, 1); Mat kernel_2_1 = (Mat_(3,3) << 0, -1, -1, 1, 1, -1, 0, 1, 0); Mat kernel_2_2 = (Mat_(3,3) << 0, 1, 0, 1, 1, -1, 0, -1, -1); Mat kernel_2_3 = (Mat_(3,3) << 0, 1, 0, -1, 1, 1, -1, -1, 0); Mat kernel_2_4 = (Mat_(3,3) << -1, -1, 0, -1, 1, 1, 0, 1, 0); do { prev = img_dst.clone(); // the first pair of structural elements img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_1_1); absdiff(img_dst, img_temp, img_dst); img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_2_1); absdiff(img_dst, img_temp, img_dst); // the second pair of structural elements img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_1_2); absdiff(img_dst, img_temp, img_dst); img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_2_2); absdiff(img_dst, img_temp, img_dst); // the third pair of structural elements img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_1_3); absdiff(img_dst, img_temp, img_dst); img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_2_3); absdiff(img_dst, img_temp, img_dst); // the fourth pair of structural elements img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_1_4); absdiff(img_dst, img_temp, img_dst); img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_2_4); absdiff(img_dst, img_temp, img_dst); absdiff(img_dst, prev, countdition); } while (countNonZero(countdition) > 0); imshow( "Binary", img ); imshow( "Hit or Mis", img_dst ); waitKey(0); return 0; } /** * Hit-or-miss transform function * * Parameters: * img The source image, 8 bit single-channel matrix * dst The destination image * kernel The kernel matrix. 1=foreground, -1=background, 0=don't care */ void hitmiss(cv::Mat& img, cv::Mat& dst, cv::Mat& kernel) { CV_Assert(img.type() == CV_8U && img.channels() == 1); Mat img_copy; cv::Mat k1 = (kernel == 1) / 255; cv::Mat k2 = (kernel == -1) / 255; cv::normalize(img, img_copy, 0, 1, cv::NORM_MINMAX); cv::Mat e1, e2; cv::erode(img_copy, e1, k1, cv::Point(-1,-1), 1, cv::BORDER_CONSTANT, cv::Scalar(0)); cv::erode(1-img_copy, e2, k2, cv::Point(-1,-1), 1, cv::BORDER_CONSTANT, cv::Scalar(0)); dst = e1 & e2; cv::normalize(dst, dst, 0, 255, cv::NORM_MINMAX); }
Pogrubienie za pomocą metody „Hit-or-Miss”.
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> void hitmiss(Mat& img, Mat& dst, Mat& kernel); int main(){ Mat img = imread("./template1.png", 1 ); cvtColor(img, img, CV_BGR2GRAY); threshold(img, img, 100, 255,THRESH_BINARY); Mat img_dst = img.clone(); Mat countdition; Mat prev; Mat img_temp; Mat kernel_1_1 = (Mat_(3,3) << -1, -1, -1, 0, 1, 0, 1, 1, 1); Mat kernel_1_2 = (Mat_(3,3) << 1, 0, -1, 1, 1, -1, 1, 0, -1); Mat kernel_1_3 = (Mat_(3,3) << 1, 1, 1, 0, 1, -1, -1, -1, -1); Mat kernel_1_4 = (Mat_(3,3) << -1, 0, 1, -1, 1, 1, -1, -1, 1); Mat kernel_2_1 = (Mat_(3,3) << 0, -1, -1, 1, 1, -1, 0, 1, 0); Mat kernel_2_2 = (Mat_(3,3) << 0, 1, 0, 1, 1, -1, 0, -1, -1); Mat kernel_2_3 = (Mat_(3,3) << 0, 1, 0, -1, 1, 1, -1, -1, 0); Mat kernel_2_4 = (Mat_(3,3) << -1, -1, 0, -1, 1, 1, 0, 1, 0); do { prev = img_dst.clone(); // the first pair of structural elements img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_1_1); add(img_dst, img_temp, img_dst); img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_2_1); add(img_dst, img_temp, img_dst); // the second pair of structural elements img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_1_2); add(img_dst, img_temp, img_dst); img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_2_2); add(img_dst, img_temp, img_dst); // the third pair of structural elements img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_1_3); add(img_dst, img_temp, img_dst); img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_2_3); add(img_dst, img_temp, img_dst); // the fourth pair of structural elements img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_1_4); add(img_dst, img_temp, img_dst); img_temp = img_dst.clone(); hitmiss(img_temp, img_temp, kernel_2_4); add(img_dst, img_temp, img_dst); absdiff(img_dst, prev, countdition); } while (countNonZero(countdition) > 0); imshow( "Binary", img ); imshow( "Hit or Mis", img_dst ); waitKey(0); return 0; } /** * Hit-or-miss transform function * * Parameters: * img The source image, 8 bit single-channel matrix * dst The destination image * kernel The kernel matrix. 1=foreground, -1=background, 0=don't care */ void hitmiss(cv::Mat& img, cv::Mat& dst, cv::Mat& kernel) { CV_Assert(img.type() == CV_8U && img.channels() == 1); Mat img_copy; cv::Mat k1 = (kernel == 1) / 255; cv::Mat k2 = (kernel == -1) / 255; cv::normalize(img, img_copy, 0, 1, cv::NORM_MINMAX); cv::Mat e1, e2; cv::erode(img_copy, e1, k1, cv::Point(-1,-1), 1, cv::BORDER_CONSTANT, cv::Scalar(0)); cv::erode(1-img_copy, e2, k2, cv::Point(-1,-1), 1, cv::BORDER_CONSTANT, cv::Scalar(0)); dst = e1 & e2; cv::normalize(dst, dst, 0, 255, cv::NORM_MINMAX); }