当前位置:网站首页>[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
边栏推荐
- 基本Dos命令
- Jinfo of JVM command: view and modify JVM configuration parameters in real time
- ST表预处理时的数组证明
- 【GNN】图解GNN: A gentle introduction(含视频)
- You don't know the complete collection of recruitment slang of Internet companies
- 哈趣投影黑马之姿,仅用半年强势突围千元投影仪市场!
- A freshman's summary of an ordinary student [I don't know whether we are stupid or crazy, but I know to run forward all the way]
- 线性代数(一)
- SubGHz, LoRaWAN, NB-IoT, 物联网
- 哈趣投影黑馬之姿,僅用半年强勢突圍千元投影儀市場!
猜你喜欢
直击2022ECDC萤石云开发者大会:携手千百行业加速智能升级
Vscode for code completion
安装VMmare时候提示hyper-v / device defender 侧通道安全性
Software testing knowledge reserve: how much do you know about the basic knowledge of "login security"?
如何在Touch Designer 2022版中设置解决Leap Motion不识别的问题?
Career experience feedback to novice programmers
3428. 放苹果
A freshman's summary of an ordinary student [I don't know whether we are stupid or crazy, but I know to run forward all the way]
当我们谈论不可变基础设施时,我们在谈论什么
Three updates to build applications for different types of devices | 2022 i/o key review
随机推荐
C语言整理(待更新)
Check point: the core element for enterprises to deploy zero trust network (ztna)
JMeter's own functions are not enough? Why don't you develop one yourself
软件测试的几个关键步骤,你需要知道
MySQL(十)
Redis(二)—Redis通用命令
PostgreSQL database timescaledb function time_ bucket_ Gapfill() error resolution and license replacement
Markdown 并排显示图片
线性代数(一)
C语言面试 写一个函数查找两个字符串中的第一个公共字符串
HKUST & MsrA new research: on image to image conversion, fine tuning is all you need
JVM 全面深入
360织语发布7.0新品 为党政军、央国企打造专属“统一数字工作空间”
How to keep accounts of expenses in life
Developers don't miss it! Oar hacker marathon phase III chain oar track registration opens
蚂蚁庄园安全头盔 7.8蚂蚁庄园答案
直击2022ECDC萤石云开发者大会:携手千百行业加速智能升级
2022Android面试必备知识点,一文全面总结
改变ui组件原有样式
c语言(结构体)定义一个User结构体,含以下字段: