当前位置:网站首页>[opencv] morphological filtering (2): open operation, morphological gradient, top hat, black hat
[opencv] morphological filtering (2): open operation, morphological gradient, top hat, black hat
2022-07-07 06:24:00 【I love to learn food】
List of articles
1、 Open operation
Open operation (Opening Operation), In fact, it is a process of corrosion before expansion , Its mathematical expression is as follows :
d s t = o p e n ( s r c , e l e m e n t ) = d i l a t e ( e r o d e ( s r c , e l e m e n t ) ) dst=open(src,element)=dilate(erode(src,element)) dst=open(src,element)=dilate(erode(src,element))
effect : Open operation can eliminate small objects , Separating objects at the finer points , And it can smooth the boundary of larger objects without significantly changing its area .
Sample code :
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
// Load the original drawing
Mat image = imread("E:\\Pec\\ Captain America .jpg");
// create a window
namedWindow("【 The original picture 】");
namedWindow("【 design sketch 】");
// Show the original image
imshow("【 The original picture 】", image);
// Define the kernel
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
// Carry out morphological operation
morphologyEx(image, image, MORPH_OPEN, element);
// Show the original image
imshow("【 design sketch 】", image);
waitKey(0);
}
2、 Closed operation
The process of expansion before corrosion is called closed operation (Closing Operation), Its mathematical expression is as follows :
d s t = c l o s e ( s r c , e l e m e n t ) = e r o d e ( d i l a t e ( s r c , e l e m e n t ) ) dst=close(src,element)=erode(dilate(src,element)) dst=close(src,element)=erode(dilate(src,element))
effect : Closed operation can eliminate small black holes ( Black areas )
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
// Load the original drawing
Mat image = imread("E:\\Pec\\ Captain America .jpg");
// create a window
namedWindow("【 The original picture 】");
namedWindow("【 design sketch 】");
// Show the original image
imshow("【 The original picture 】", image);
// Define the kernel
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
// Carry out morphological operation
morphologyEx(image, image, MORPH_CLOSE, element);
// Show the original image
imshow("【 design sketch 】", image);
waitKey(0);
}
3、 Morphological gradients
Morphological gradients (Morphological Gradient) It is the difference between expansive soil and corrosion diagram , The mathematical expression is as follows :
d s t = m o r p h − g r a d ( s r c , e l e m e n t ) = d i l a t e ( s r c , e l e m e n t ) − e r o d e ( s r c , e l e m e n t ) dst=morph-grad(src,element)=dilate(src,element)-erode(src,element) dst=morph−grad(src,element)=dilate(src,element)−erode(src,element)
effect : The binary image can be lumped (blob) The edge of the protrudes , Using morphological gradient to preserve the edge contour of the object .
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
// Load the original drawing
Mat image = imread("E:\\Pec\\ Captain America .jpg");
// create a window
namedWindow("【 The original picture 】");
namedWindow("【 design sketch 】");
// Show the original image
imshow("【 The original picture 】", image);
// Define the kernel
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
// Carry out morphological operation
morphologyEx(image, image, MORPH_GRADIENT, element);
// Show the original image
imshow("【 design sketch 】", image);
waitKey(0);
}
4、 Top hat
Top hat operation (Top Hat) It is often translated into “ formal hat ” operation , It's the original image and the one just introduced above “ Open operation ” The difference between the results of .
d s t = t o p h a t ( s r c , e l e m e n t ) = s r c − o p e n ( s r c , e l e m e n t ) dst=tophat(src,element)=src-open(src,element) dst=tophat(src,element)=src−open(src,element)
Because the result of the open operation is to enlarge the crack or local low brightness area . therefore , Subtract the calculated graph from the original graph , The resulting rendering highlights a brighter area than the area around the outline of the original image , And this operation is related to the size of the selected core .
effect : Top hat operations are often used to separate patches that are lit up near neighbors . In an image with a large background , When small objects are more regular , You can use the top hat operation to advance the background .
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
// Load the original drawing
Mat image = imread("E:\\Pec\\ Captain America .jpg");
// create a window
namedWindow("【 The original picture 】");
namedWindow("【 design sketch 】");
// Show the original image
imshow("【 The original picture 】", image);
// Define the kernel
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
// Carry out morphological operation
morphologyEx(image, image, MORPH_TOPHAT, element);
// Show the original image
imshow("【 design sketch 】", image);
waitKey(0);
}
5、 Black hat
Black hat (Black Hat) Operation is the difference between the result of closed operation and the original image , The mathematical expression is :
d s t = b l a c k h a t ( s r c , e l e m e n t ) = c l o s e ( s r c , e l e m e n t ) − s r c dst=blackhat(src,element)=close(src,element)-src dst=blackhat(src,element)=close(src,element)−src
The effect image after black hat operation highlights the darker area than the area around the outline of the original image , And this operation is related to the size of the selected core .
effect : Black hat operation is used to separate patches darker than adjacent points , The rendering has a very perfect outline .
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
// Load the original drawing
Mat image = imread("E:\\Pec\\ Captain America .jpg");
// create a window
namedWindow("【 The original picture 】");
namedWindow("【 design sketch 】");
// Show the original image
imshow("【 The original picture 】", image);
// Define the kernel
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
// Carry out morphological operation
morphologyEx(image, image, MORPH_BLACKHAT, element);
// Show the original image
imshow("【 design sketch 】", image);
waitKey(0);
}
6、 The core API function :morphologyEx()
void morphologyEx(
InputArray src,
OutputArray dst,
int op,
InputArray kernel,
Pointanchor=Point(-1,-1),
int iteration=1,
int borderType=BORDER_CONSTANT,
const Scalar& borderValue=morphologyDefaultBorderValue()
);
The first parameter : The input image , Source image , fill Mat Class . The image bit depth should be 5 One of the species :CV_8U、CV_16U、CV_16S、CV_32F and CV_64F
The second parameter : The target image , The output parameters of the function , Need the same size and type as the source image
The third parameter :int Type of op, Indicates the type of morphological operation , It can be any identifier in the following table
[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-G93BBVtQ-1656987857859)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20220705095322440.png)]
Fourth parameter :InputArray Type of kernel, The kernel of morphological operation . if NULL, It means that the reference point is located at the center 3x3 The core of . Generally use functions getStructuringElement With the use of this parameter .getStructuringElement The function returns the structural elements of the specified shape and size ( Kernel matrix )
getStructuringElement The first parameter of the function represents the shape of the kernel :
- (1) rectangular ——MORPH_RECT
- (2) Crisscross ——MORPH_CROSS
- (3) ellipse ——MORPH_ELLIPSE
and getStructuringElement The second and third parameters of the function are the size of the kernel and the location of the anchor point respectively
It's called erode and dilate Function before , First define a Mat Type to get getStructuringElement The return value of the function , For the location of the anchor , Have default values (-1,-1), Indicates that the anchor point is in the center . Also note : Cross shaped element The shape only depends on the position of the anchor . And in other cases , Anchor points only affect the offset of morphological operation results
//getStructuringElement Function related calls are as follows : int g_nStructuringElement(MORPH_RECT,Size(2*g_nStructuringElement+1, 2*g_nStructuringElement+1),Point(g_nStructuringElement,g_nStructuringElement));
Then you can call erode、dilate or morphologyEx Function time , from kernel Fill in and save the parameters getStructuringElement The return value of Mat Type variable .
Fifth parameter : The position of the anchor , The default value is (-1,-1), The anchor point is in the center
Sixth parameter : Number of iterations using the function , The default value is 1.
Seventh parameter : Some kind of boundary pattern used to infer pixels outside the image . Have default values BORDER_CONSTANT
Eighth parameter : The boundary value when the boundary is constant , Have default values morphologyDEfaultBorderValue(), Generally, it does not need to be considered . These operations can be carried out locally (in-place) operation , And for multi-channel images , Each channel operates separately .
7、 Comprehensive examples : Morphological filtering
explain : The following program running examples will appear 4 A window displaying images , Contains the original graph 、 open \ A closed operation , inflation \ Corrode one , Top hat \ Black hat operation one . They use scroll bars... Respectively , To control the morphological effect , And the iteration value is 10 It's the middle point when . Besides , You can also use the keyboard 1、2、3 And the space bar to adjust the structure of different elements
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
//-----------------
// Global variable declaration
//---------------------
Mat g_srcImage, g_dstImage;
int g_nElementShape = MORPH_RECT;// The shape of the element result
//-----------------------------------------
// Variables accept TrackBar Positional arguments
//------------------------------------------
int g_nMaxIterationNum = 10;
int g_nOpenCloseNum = 0;
int g_nErodeDilateNum = 0;
int g_nTopBlackHatNum = 0;
//--------------------------------------------
// Global function declaration
//-------------------------------------------
static void on_OpenClose(int, void*);
static void on_ErodeDilate(int, void*);
static void on_TopBlackHat(int ,void*);
static void ShowHelpText();// Help me with text display
int main()
{
system("color 5E");
// Load the original drawing
g_srcImage = imread("E:\\Pec\\ Iron man .jpg");
if (!g_srcImage.data) {
printf(" Picture reading error \n");
return false;
}
// Show the original image
namedWindow("【 The original picture 】");
imshow("【 The original picture 】", g_srcImage);
// Create three windows
namedWindow("【 Open operation / Closed operation 】", 1);
namedWindow("【 corrosion / inflation 】", 1);
namedWindow("【 Top hat / Black hat 】", 1);
// parameter assignment
g_nOpenCloseNum = 9;
g_nErodeDilateNum = 9;
g_nTopBlackHatNum = 9;
// Create track bars for three windows respectively
createTrackbar(" Iteration value ", "【 Open operation / Closed operation 】", &g_nOpenCloseNum, g_nMaxIterationNum * 2 + 1, on_OpenClose);
createTrackbar(" Iteration value ", "【 corrosion / inflation 】", &g_nErodeDilateNum, g_nErodeDilateNum * 2 + 1, on_ErodeDilate);
createTrackbar(" Iteration value ", "【 Top hat / Black hat 】", &g_nTopBlackHatNum, g_nTopBlackHatNum * 2 + 1, on_TopBlackHat);
printf("----------------------------------------------------------------------\n");
printf("| Operation instructions |\n");
printf("| Press the keyboard Q perhaps ESC, Program exit |\n");
printf("| Press the keyboard 1, Use ellipses (Elliptic) Structure original structure elements MORPH_ELLIPSE| |\n");
printf("| Press the keyboard 2, Use rectangles (Rectangle) Structure original structure elements MORPH_RECT |\n");
printf("| Press the keyboard 3, Use a cross (Cross-shaped) Structure original structure elements MORPH_CROSS |\n");
printf("| Press the keyboard space, In the rectangle 、 Cycle between ellipse and cross |\n");
printf("-------------------------------------------------------------------\n");
// Polling for key information
while (1)
{
int c;
// Execute callback function
on_OpenClose(g_nOpenCloseNum, 0);
on_ErodeDilate(g_nErodeDilateNum, 0);
on_TopBlackHat(g_nTopBlackHatNum, 0);
c = waitKey(0);
// Press the keyboard Q perhaps ESC, Program exit
if ((char)c == 'q' || (char)c == 27)
break;
// Press the keyboard 1, Use ellipses (Elliptic) Structure original structure elements MORPH_ELLIPSE
else if ((char)c == 49)//1 Of ASII Code for 49
g_nElementShape = MORPH_ELLIPSE;
// Press the keyboard 2, Use rectangles (Rectangle) Structure original structure elements MORPH_RECT
else if ((char)c == 50)
g_nElementShape = MORPH_RECT;
// Press the keyboard 3, Use a cross (Cross-shaped) Structure original structure elements MORPH_CROSS
else if ((char)c == 51)
g_nElementShape = MORPH_CROSS;
// Press the keyboard space, In the rectangle 、 Cycle between ellipse and cross
else if ((char)c == ' ')
g_nElementShape = (g_nElementShape + 1) % 3;
}
return 0;
}
static void on_OpenClose(int, void*)
{
// Definition of offset
int offset = g_nOpenCloseNum - g_nMaxIterationNum;// Offset
int Absolute_offset = offset > 0 ? offset : -offset;// Take a positive value
// Custom core
Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
// To operate
if (offset < 0)
morphologyEx(g_srcImage, g_dstImage, CV_MOP_OPEN, element);
else
morphologyEx(g_srcImage, g_dstImage,MORPH_CLOSE, element);
imshow("【 Open operation / Closed operation 】", g_dstImage);
}
static void on_ErodeDilate(int, void*)
{
// Definition of offset
int offset = g_nErodeDilateNum - g_nMaxIterationNum;// Offset
int Absolute_offset = offset > 0 ? offset : -offset;// Take a positive value
// Custom core
Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
// To operate
if (offset < 0)
erode(g_srcImage, g_dstImage,element);
else
dilate(g_srcImage, g_dstImage, element);
imshow("【 corrosion / inflation 】", g_dstImage);
}
static void on_TopBlackHat(int, void*)
{
// Definition of offset
int offset = g_nTopBlackHatNum - g_nMaxIterationNum;// Offset
int Absolute_offset = offset > 0 ? offset : -offset;// Take a positive value
// Custom core
Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
// To operate
if (offset < 0)
morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT, element);
else
morphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);
imshow("【 Top hat / Black hat 】", g_dstImage);
}
Original image :
Open operation 、 corrosion 、 Top hat image
Closed operation 、 inflation 、 Black hat image
边栏推荐
猜你喜欢
Three updates to build applications for different types of devices | 2022 i/o key review
Jinfo of JVM command: view and modify JVM configuration parameters in real time
安装VMmare时候提示hyper-v / device defender 侧通道安全性
Ideas of high concurrency and high traffic seckill scheme
进程间通信之共享内存
ETCD数据库源码分析——从raftNode的start函数说起
高并发大流量秒杀方案思路
window下面如何安装swoole
屏幕程序用串口无法调试情况
[SOC FPGA] custom IP PWM breathing lamp
随机推荐
POI导出Excel:设置字体、颜色、行高自适应、列宽自适应、锁住单元格、合并单元格...
Three updates to build applications for different types of devices | 2022 i/o key review
JMeter's own functions are not enough? Why don't you develop one yourself
k8s运行oracle
Ideas of high concurrency and high traffic seckill scheme
JVM 全面深入
693. Travel sequencing
ceres-solver和g2o性能比较
Markdown 并排显示图片
tkinter窗口选择pcd文件并显示点云(open3d)
ICML 2022 | 探索语言模型的最佳架构和训练方法
Crudini profile editing tool
ICML 2022 | explore the best architecture and training method of language model
Jstack of JVM command: print thread snapshots in JVM
那些自损八百的甲方要求
Symmetric binary tree [tree traversal]
基本Dos命令
Matlab / envi principal component analysis implementation and result analysis
直击2022ECDC萤石云开发者大会:携手千百行业加速智能升级
JVM command - jmap: export memory image file & memory usage