开操作:open
闭操作
形态学梯度 - Morphological Gradient
顶帽 - top hat
黑帽
#include
#include
#include
#include
using namespace std;
using namespace cv;
int main() {
std::string path = "../fei.JPG";
cv::Mat img = cv::imread(path, 5);
string str_input = "input image";
string str_output = "output image";
if(img.empty())
{
std::cout << "open file failed" << std::endl;
return -1;
}
//开闭、顶黑帽操作
Mat kernel = getStructuringElement(MORPH_RECT, Size(11, 11), Point(-1, -1));
Mat dest1, dest2, dest3,dest4;
//CV_MOP_OPEN定义在 #include 头文件中,需要包含进来
morphologyEx(img, dest1, CV_MOP_OPEN, kernel);
imshow(str_input, img);
imshow("open image", dest1);
morphologyEx(img, dest2, CV_MOP_CLOSE, kernel);
imshow(str_input, img);
imshow("close image", dest2);
morphologyEx(img, dest3, CV_MOP_BLACKHAT, kernel);
imshow(str_input, img);
imshow("black hat image", dest3);
morphologyEx(img, dest4, CV_MOP_TOPHAT, kernel);
imshow(str_input, img);
imshow("top hat image", dest4);
Mat dest5, dest6, dest7;
morphologyEx(img, dest5, CV_MOP_ERODE, kernel);
imshow(str_input, img);
imshow("erode image", dest5);
morphologyEx(img, dest6, CV_MOP_DILATE, kernel);
imshow(str_input, img);
imshow("dilate image", dest6);
morphologyEx(img, dest7, CV_MOP_GRADIENT, kernel);
imshow(str_input, img);
imshow("gradient image", dest7);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
显示结果:
注: 其中,CV_MOP_OPEN
定义在
头文件中,在clion IDE中需要包含该头文件才能编译通过,可以看到该头文件中还包括以下几个枚举值,
enum {
CV_MOP_ERODE =0,
CV_MOP_DILATE =1,
CV_MOP_OPEN =2,
CV_MOP_CLOSE =3,
CV_MOP_GRADIENT =4,
CV_MOP_TOPHAT =5,
CV_MOP_BLACKHAT =6
}
其中使用了CV_MOP_ERODE
、CV_MOP_DILATE
,发现和前面调用erode
、dilate
函数的结果一致,morphologyEx
调用和erode
函数调用是否有区别(从图像看出来效果是一样的),有待进一步探索、学习。
erode
函数,所以两个是一样的效果在这里插入代码片erode
的代价更小一些。void morphologyEx( InputArray _src, OutputArray _dst, int op,
InputArray _kernel, Point anchor, int iterations,
int borderType, const Scalar& borderValue )
{
CV_INSTRUMENT_REGION();
Mat kernel = _kernel.getMat();
if (kernel.empty())
{
kernel = getStructuringElement(MORPH_RECT, Size(3,3), Point(1,1));
}
#ifdef HAVE_OPENCL
Size ksize = kernel.size();
anchor = normalizeAnchor(anchor, ksize);
CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2 && _src.channels() <= 4 &&
anchor.x == ksize.width >> 1 && anchor.y == ksize.height >> 1 &&
borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue(),
ocl_morphologyEx(_src, _dst, op, kernel, anchor, iterations, borderType, borderValue))
#endif
Mat src = _src.getMat(), temp;
_dst.create(src.size(), src.type());
Mat dst = _dst.getMat();
#if !IPP_DISABLE_MORPH_ADV
//CV_IPP_RUN_FAST(ipp_morphologyEx(op, src, dst, kernel, anchor, iterations, borderType, borderValue));
#endif
switch( op )
{
case MORPH_ERODE:
erode( src, dst, kernel, anchor, iterations, borderType, borderValue );
break;
case MORPH_DILATE:
dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );
break;
case MORPH_OPEN:
erode( src, dst, kernel, anchor, iterations, borderType, borderValue );
dilate( dst, dst, kernel, anchor, iterations, borderType, borderValue );
break;
case MORPH_CLOSE:
dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );
erode( dst, dst, kernel, anchor, iterations, borderType, borderValue );
break;
case MORPH_GRADIENT:
erode( src, temp, kernel, anchor, iterations, borderType, borderValue );
dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );
dst -= temp;
break;
case MORPH_TOPHAT:
if( src.data != dst.data )
temp = dst;
erode( src, temp, kernel, anchor, iterations, borderType, borderValue );
dilate( temp, temp, kernel, anchor, iterations, borderType, borderValue );
dst = src - temp;
break;
case MORPH_BLACKHAT:
if( src.data != dst.data )
temp = dst;
dilate( src, temp, kernel, anchor, iterations, borderType, borderValue );
erode( temp, temp, kernel, anchor, iterations, borderType, borderValue );
dst = temp - src;
break;
case MORPH_HITMISS:
CV_Assert(src.type() == CV_8UC1);
if(countNonZero(kernel) <=0)
{
src.copyTo(dst);
break;
}
{
Mat k1, k2, e1, e2;
k1 = (kernel == 1);
k2 = (kernel == -1);
if (countNonZero(k1) <= 0)
e1 = Mat(src.size(), src.type(), Scalar(255));
else
erode(src, e1, k1, anchor, iterations, borderType, borderValue);
if (countNonZero(k2) <= 0)
e2 = Mat(src.size(), src.type(), Scalar(255));
else
{
Mat src_complement;
bitwise_not(src, src_complement);
erode(src_complement, e2, k2, anchor, iterations, borderType, borderValue);
}
dst = e1 & e2;
}
break;
default:
CV_Error( CV_StsBadArg, "unknown morphological operation" );
}
}