Skip to content

Instantly share code, notes, and snippets.

@bradmontgomery
Last active December 14, 2015 13:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradmontgomery/5096641 to your computer and use it in GitHub Desktop.
Save bradmontgomery/5096641 to your computer and use it in GitHub Desktop.
Some rather dated examples of Mophological operations using OpenCV. I wrote briefly about them at one point (https://bradmontgomery.net/blog/morphology-is-fun/), but I'm moving the sample code here.
//----------------------------------------
// Perform Image Dilation on input image,
// saving the result to an input image.
//
// USAGE: dilate <input_image> <output_image> [iterations]
//
// Version: 2009.01.04
//
// Copyright (c) 2009, Brad Montgomery <brad@bradmontgomery.net>
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//----------------------------------------
#include "cv.h"
#include "highgui.h"
#include <iostream>
#include <stdlib.h>
// used for cvLoadImage()
#define CV_LOAD_IMAGE_COLOR 1
#define CV_LOAD_IMAGE_GRAYSCALE 0
#define CV_LOAD_IMAGE_UNCHANGED -1
//#define SHOW_OUTPUT 1
using namespace std;
int main (int argc, char** argv) {
char* input_filename;
char* output_filename;
IplImage* input_image;
IplImage* output_image;
int iterations = 1;
#ifdef SHOW_OUTPUT
const char* input_win = "Original Image";
const char* output_win = "Dilated Image";
#endif
int key;
if( argc == 3 ){
input_filename = argv[1];
output_filename = argv[2];
}else if(argc == 4){
input_filename = argv[1];
output_filename = argv[2];
iterations = atoi(argv[3]);
}else{
cerr << "USAGE: dilate <input_image> <output_image> [iterations=1]\n";
exit(1);
}
// load the image
input_image = cvLoadImage(input_filename, CV_LOAD_IMAGE_UNCHANGED);
output_image = cvCloneImage(input_image);
cout << "- Cloned input as output image\n";
// void cvDilate( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL,
// int iterations=1 );
// if element=NULL, a 3x3 rectangular structuring element is used.
cvDilate(input_image, output_image, NULL, iterations);
#ifdef SHOW_OUTPUT
//create windows
if(!cvNamedWindow(input_win, CV_WINDOW_AUTOSIZE)){
std::cout << "Could not create window";
return -1;
}
if(!cvNamedWindow(output_win, CV_WINDOW_AUTOSIZE)){
std::cout << "Could not create window";
return -1;
}
// show the image in the window
cvShowImage(input_win, input_image);
cvShowImage(output_win, output_image);
// Wait for a number of miliseconds,
// 0 == infinity
key = cvWaitKey(0);
#endif
// Save the Output Image
// int cvSaveImage( const char* filename, const CvArr* image );
cvSaveImage(output_filename, output_image);
cout << "Image saved as " << output_filename << "\n done.\n\n";
cvReleaseImage( &input_image );
cvReleaseImage( &output_image );
return 0;
}
//----------------------------------------
// Perform Image Erosion on input image,
// saving the result to an input image.
//
// USAGE: erode <input_image> <output_image> [iterations]
//
// Version: 2009.01.04
//
// Copyright (c) 2009, Brad Montgomery <brad@bradmontgomery.net>
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//----------------------------------------
#include "cv.h"
#include "highgui.h"
#include <iostream>
#include <stdlib.h>
// used for cvLoadImage()
#define CV_LOAD_IMAGE_COLOR 1
#define CV_LOAD_IMAGE_GRAYSCALE 0
#define CV_LOAD_IMAGE_UNCHANGED -1
//#define SHOW_OUTPUT 1
using namespace std;
int main (int argc, char** argv) {
char* input_filename;
char* output_filename;
IplImage* input_image;
IplImage* output_image;
int iterations = 1;
#ifdef SHOW_OUTPUT
const char* input_win = "Original Image";
const char* output_win = "Eroded Image";
#endif
int key;
if( argc == 3 ){
input_filename = argv[1];
output_filename = argv[2];
}else if(argc == 4){
input_filename = argv[1];
output_filename = argv[2];
iterations = atoi(argv[3]);
}else{
cerr << "USAGE: erode <input_image> <output_image> [iterations=1]\n";
exit(1);
}
// load the image
input_image = cvLoadImage(input_filename, CV_LOAD_IMAGE_UNCHANGED);
output_image = cvCloneImage(input_image);
cout << "- Cloned input as output image\n";
// void cvErode( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL,
// int iterations=1 );
// if element=NULL, a 3×3 rectangular structuring element is used.
cvErode(input_image, output_image, NULL, iterations);
#ifdef SHOW_OUTPUT
//create windows
if(!cvNamedWindow(input_win, CV_WINDOW_AUTOSIZE)){
std::cout << "Could not create window";
return -1;
}
if(!cvNamedWindow(output_win, CV_WINDOW_AUTOSIZE)){
std::cout << "Could not create window";
return -1;
}
// show the image in the window
cvShowImage(input_win, input_image);
cvShowImage(output_win, output_image);
// Wait for a number of miliseconds,
// 0 == infinity
key = cvWaitKey(0);
#endif
// Save the Output Image
// int cvSaveImage( const char* filename, const CvArr* image );
cvSaveImage(output_filename, output_image);
cout << "Image saved as " << output_filename << "\n done.\n\n";
cvReleaseImage( &input_image );
cvReleaseImage( &output_image );
return 0;
}
//----------------------------------------
// Perform Morphological Operations on an image,
// saving the result to an input image.
//
// USAGE: morphology <input_image> <output_image> [shape] [operation] [iterations]
//
// Version: 2009.01.04
//
// Copyright (c) 2009, Brad Montgomery <brad@bradmontgomery.net>
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//----------------------------------------
#include "cv.h"
#include "highgui.h"
#include <iostream>
#include <cstdlib>
#include <cstring>
// used for cvLoadImage()
#define CV_LOAD_IMAGE_COLOR 1
#define CV_LOAD_IMAGE_GRAYSCALE 0
#define CV_LOAD_IMAGE_UNCHANGED -1
//#define SHOW_OUTPUT 1
using namespace std;
int main (int argc, char** argv) {
char* input_filename;
char* output_filename;
IplImage* input_image;
IplImage* output_image;
IplImage* temp_image;
// Default parameters for Structuring Element
int cols = 3;
int rows = 3;
int anchor_x = 0;
int anchor_y = 0;
int shape = CV_SHAPE_RECT;
// Morphology paramters
int operation = CV_MOP_OPEN;
int iterations = 1;
#ifdef SHOW_OUTPUT
const char* input_win = "Original Image";
const char* output_win = "Output Image";
#endif
int key;
cout << "\n-----------------------------------------\n";
if( argc == 3 ){
input_filename = argv[1];
output_filename = argv[2];
}else if(argc == 6){
input_filename = argv[1];
output_filename = argv[2];
cout << "Shape: '" << argv[3] << "'\n";
if(strcmp(argv[3], "rectangle") == 0) shape = CV_SHAPE_RECT;
else if(strcmp(argv[3], "cross") == 0) shape = CV_SHAPE_CROSS;
else if(strcmp(argv[3], "ellipse")== 0) shape = CV_SHAPE_ELLIPSE;
else shape= CV_SHAPE_RECT;
cout << "Operation: '" << argv[4] << "'\n";
if(strcmp(argv[4], "open") == 0) operation = CV_MOP_OPEN;
else if(strcmp(argv[4],"close") == 0) operation = CV_MOP_CLOSE;
else if(strcmp(argv[4],"gradient") == 0) operation = CV_MOP_GRADIENT;
else if(strcmp(argv[4],"tophat") == 0) operation = CV_MOP_TOPHAT;
else if(strcmp(argv[4],"blackhat") == 0) operation = CV_MOP_BLACKHAT;
else operation = CV_MOP_OPEN;
iterations = atoi(argv[5]);
cout << "Iterations: " << iterations << "\n";
}else{
cerr << "USAGE: morphology <input_image> <output_image> ";
cerr << " [shape=rect] [operation=open] [iterations=1]\n";
cerr << " shape can be 'rectangle', 'cross', or 'ellipse'\n";
cerr << " operation can be 'open', 'close', 'gradient', 'tophat', or 'blackhat'\n";
exit(1);
}
// load the image
input_image = cvLoadImage(input_filename, CV_LOAD_IMAGE_UNCHANGED);
output_image = cvCloneImage(input_image);
temp_image = cvCloneImage(input_image);
//cout << "- Cloned input as output image\n";
// IplConvKernel*
// cvCreateStructuringElementEx( int cols, // number of columns
// int rows, // number of rows
// int anchor_x, // relative horizontal offset
// int anchor_y, // " vertical offset
// int shape, // (see below)
// int* values=NULL ); // values for custom shape
// shape can be:
// CV_SHAPE_RECT, a rectangular element;
// CV_SHAPE_CROSS, a cross-shaped element;
// CV_SHAPE_ELLIPSE, an elliptic element;
// CV_SHAPE_CUSTOM, a user
IplConvKernel* element = cvCreateStructuringElementEx(rows, cols, anchor_x, anchor_y,
shape, NULL);
//void cvMorphologyEx( const CvArr* src, CvArr* dst, CvArr* temp,
// IplConvKernel* element, int operation, int iterations=1 );
// Operation can be one of the following:
// CV_MOP_OPEN - opening
// CV_MOP_CLOSE - closing
// CV_MOP_GRADIENT - morphological gradient
// CV_MOP_TOPHAT - "top hat"
// CV_MOP_BLACKHAT - "black hat"
cvMorphologyEx(input_image, output_image, temp_image, element, operation, iterations);
cout << "Ran cvMophologyEx with 3x3 element of (shape: "<<shape<<", operation: " << operation << ")\n\n";
// void cvReleaseStructuringElement( IplConvKernel** element );
cvReleaseStructuringElement( &element );
#ifdef SHOW_OUTPUT
//create windows
if(!cvNamedWindow(input_win, CV_WINDOW_AUTOSIZE)){
std::cout << "Could not create window";
return -1;
}
if(!cvNamedWindow(output_win, CV_WINDOW_AUTOSIZE)){
std::cout << "Could not create window";
return -1;
}
// show the image in the window
cvShowImage(input_win, input_image);
cvShowImage(output_win, output_image);
// Wait for a number of miliseconds,
// 0 == infinity
key = cvWaitKey(0);
#endif
// Save the Output Image
// int cvSaveImage( const char* filename, const CvArr* image );
cvSaveImage(output_filename, output_image);
cout << "Image saved as " << output_filename << "\n done.\n\n";
cvReleaseImage( &input_image );
cvReleaseImage( &output_image );
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment