高级图像处理是指在基础图像处理(如滤波、边缘检测等)的基础上,进一步实现更复杂的任务,例如图像分割、轮廓检测、形态学操作、直方图处理等。这些技术广泛应用于目标检测、图像分析、医学影像处理等领域。
高级图像处理的应用场景
医学影像分析:
使用图像分割技术提取病变区域。
使用形态学操作去除噪声。
目标检测与跟踪:
使用轮廓检测和模板匹配定位目标。
使用直方图处理增强目标特征。
图像增强:
使用直方图均衡化提高图像对比度。
使用分水岭算法分离重叠对象。
图像分割
图像分割是图像处理中的一个重要步骤,它将图像划分为多个区域或对象,以便于进一步的分析和处理。常见的图像分割方法包括基于阈值的分割、基于边缘的分割和基于区域的分割。
基于阈值的分割
基于阈值的分割是最简单的图像分割方法之一。它通过设定一个或多个阈值,将图像的像素值分为不同的类别。常见的阈值分割方法包括全局阈值和自适应阈值。
全局阈值分割
全局阈值分割使用一个固定的阈值将图像分为前景和背景。OpenCV 提供了 cv::threshold
函数来实现这一功能。
cv :: Mat src = cv :: imread ( "image.jpg" , cv :: IMREAD_GRAYSCALE );
cv :: Mat dst ;
cv :: threshold ( src , dst , 128 , 255 , cv :: THRESH_BINARY );
以上代码中,128 是阈值,255 是最大像素值,cv::THRESH_BINARY 表示使用二值化方法。
自适应阈值分割
自适应阈值分割根据图像的局部区域动态调整阈值。OpenCV 提供了 cv::adaptiveThreshold
函数来实现这一功能。
cv :: Mat src = cv :: imread ( "image.jpg" , cv :: IMREAD_GRAYSCALE );
cv :: Mat dst ;
cv :: adaptiveThreshold ( src , dst , 255 , cv :: ADAPTIVE_THRESH_MEAN_C , cv :: THRESH_BINARY , 11 , 2 );
以上代码中,255 是最大像素值,cv::ADAPTIVE_THRESH_MEAN_C 表示使用局部均值作为阈值,11
是邻域大小,2 是常数。
基于边缘的分割
基于边缘的分割通过检测图像中的边缘来分割图像。常见的边缘检测算法包括 Canny 边缘检测和
Sobel 算子。
Canny 边缘检测
Canny 边缘检测是一种多阶段的边缘检测算法。OpenCV 提供了 cv::Canny 函数来实现这一功能。
cv :: Mat src = cv :: imread ( "image.jpg" , cv :: IMREAD_GRAYSCALE );
cv :: Mat edges ;
cv :: Canny ( src , edges , 100 , 200 );
以上代码中,100 和 200 是 Canny 算法的两个阈值。
基于区域的分割(分水岭算法)
基于区域的分割通过将图像划分为多个区域来实现分割。分水岭算法是一种常用的基于区域的分割方法。
分水岭算法
分水岭算法将图像视为地形图,通过模拟水流的扩散来分割图像。OpenCV 提供了 cv::watershed
函数来实现这一功能。
cv :: Mat src = cv :: imread ( "image.jpg" );
cv :: Mat markers = cv :: Mat :: zeros ( src . size (), CV_32S );
cv :: watershed ( src , markers );
以上代码中,markers 是标记矩阵,用于存储分割结果。
轮廓检测
轮廓检测是图像处理中的一个重要步骤,它用于检测图像中的对象边界。OpenCV 提供了多种轮廓检测和处理的函数。
查找轮廓
查找轮廓是轮廓检测的第一步。OpenCV 提供了 cv::findContours 函数来实现这一功能。
cv :: Mat src = cv :: imread ( "image.jpg" , cv :: IMREAD_GRAYSCALE );
std :: vector < std :: vector < cv :: Point >> contours ;
std :: vector < cv :: Vec4i > hierarchy ;
cv :: findContours ( src , contours , hierarchy , cv :: RETR_TREE , cv :: CHAIN_APPROX_SIMPLE );
以上代码中,contours 是存储轮廓的向量,hierarchy 是存储轮廓层次结构的向量。
轮廓特征
轮廓特征包括面积、周长、边界框等。OpenCV 提供了多种函数来计算这些特征。
面积
面积是轮廓的一个重要特征。OpenCV 提供了 cv::contourArea 函数来计算轮廓的面积。
double area = cv :: contourArea ( contours [ 0 ]);
周长
周长是轮廓的另一个重要特征。OpenCV 提供了 cv::arcLength 函数来计算轮廓的周长。
double perimeter = cv :: arcLength ( contours [ 0 ], true );
边界框
边界框是轮廓的最小外接矩形。OpenCV 提供了 cv::boundingRect 函数来计算边界框。
cv :: Rect rect = cv :: boundingRect ( contours [ 0 ]);
轮廓绘制
轮廓绘制是将检测到的轮廓绘制到图像上。OpenCV 提供了 cv::drawContours
函数来实现这一功能。
cv :: Mat dst = cv :: Mat :: zeros ( src . size (), CV_8UC3 );
cv :: drawContours ( dst , contours , - 1 , cv :: Scalar ( 0 , 255 , 0 ), 2 );
以上代码中,dst 是绘制轮廓后的图像,cv::Scalar(0, 255, 0) 是轮廓的颜色,2
是轮廓的线宽。
模板匹配
模板匹配是一种在图像中查找特定模板的方法。OpenCV 提供了 cv::matchTemplate
函数来实现这一功能。
单模板匹配
单模板匹配是在图像中查找一个模板。OpenCV 提供了 cv::matchTemplate
函数来实现这一功能。
cv :: Mat src = cv :: imread ( "image.jpg" );
cv :: Mat templ = cv :: imread ( "template.jpg" );
cv :: Mat result ;
cv :: matchTemplate ( src , templ , result , cv :: TM_CCOEFF_NORMED );
以上代码中,result 是匹配结果矩阵,cv::TM_CCOEFF_NORMED 是匹配方法。
多模板匹配
多模板匹配是在图像中查找多个模板。可以通过遍历匹配结果矩阵来实现多模板匹配。
double minVal , maxVal ;
cv :: Point minLoc , maxLoc ;
cv :: minMaxLoc ( result , & minVal , & maxVal , & minLoc , & maxLoc );
以上代码中,maxLoc 是匹配结果的最大值位置。
实例
分水岭算法
实例
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( ) {
// 读取图像
Mat image = imread( "objects.jpg" ) ;
if ( image.empty ( ) ) {
cout << "错误:无法加载图像,请检查路径是否正确。" << endl;
return - 1 ;
}
// 转换为灰度图像
Mat gray;
cvtColor( image, gray, COLOR_BGR2GRAY) ;
// 二值化
Mat binary;
threshold( gray, binary, 0 , 255 , THRESH_BINARY_INV + THRESH_OTSU) ;
// 去除噪声
Mat kernel = getStructuringElement( MORPH_RECT, Size( 3 , 3 ) ) ;
morphologyEx( binary, binary, MORPH_OPEN, kernel, Point( - 1 , - 1 ) , 2 ) ;
// 计算距离变换
Mat dist;
distanceTransform( binary, dist, DIST_L2, 5 ) ;
// 归一化距离变换图像
normalize( dist, dist, 0 , 1.0 , NORM_MINMAX) ;
// 二值化距离变换图像
threshold( dist, dist, 0.5 , 1.0 , THRESH_BINARY) ;
// 查找轮廓
Mat dist_8u;
dist.convertTo ( dist_8u, CV_8U) ;
vector< vector< Point>> contours;
findContours( dist_8u, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE) ;
// 创建标记图像
Mat markers = Mat:: zeros ( dist.size ( ) , CV_32S) ;
for ( size_t i = 0 ; i < contours.size ( ) ; i++ ) {
drawContours( markers, contours, static_cast < int > ( i) , Scalar( static_cast < int > ( i) + 1 ) , - 1 ) ;
}
// 应用分水岭算法
watershed( image, markers) ;
// 显示结果
Mat result = image.clone ( ) ;
for ( int i = 0 ; i < markers.rows ; i++ ) {
for ( int j = 0 ; j < markers.cols ; j++ ) {
if ( markers.at < int > ( i, j) == - 1 ) {
result.at < Vec3b> ( i, j) = Vec3b( 0 , 255 , 0 ) ; // 标记边界为绿色
}
}
}
imshow( "Watershed Result" , result) ;
waitKey( 0 ) ;
return 0 ;
}
轮廓检测
轮廓检测用于提取图像中对象的边界。
OpenCV 提供了 findContours 函数来检测轮廓。
实例
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( ) {
// 读取图像
Mat image = imread( "objects.jpg" ) ;
if ( image.empty ( ) ) {
cout << "错误:无法加载图像,请检查路径是否正确。" << endl;
return - 1 ;
}
// 转换为灰度图像
Mat gray;
cvtColor( image, gray, COLOR_BGR2GRAY) ;
// 二值化
Mat binary;
threshold( gray, binary, 0 , 255 , THRESH_BINARY_INV + THRESH_OTSU) ;
// 查找轮廓
vector< vector< Point>> contours;
vector< Vec4i> hierarchy;
findContours( binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE) ;
// 绘制轮廓
Mat result = Mat:: zeros ( image.size ( ) , CV_8UC3) ;
for ( size_t i = 0 ; i < contours.size ( ) ; i++ ) {
drawContours( result, contours, i, Scalar( 0 , 255 , 0 ) , 2 ) ;
}
// 显示结果
imshow( "Contours" , result) ;
waitKey( 0 ) ;
return 0 ;
}
形态学操作
形态学操作是基于形状的图像处理技术,常用于去除噪声、分离对象等。
实例
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( ) {
// 读取图像
Mat image = imread( "noisy_image.jpg" ) ;
if ( image.empty ( ) ) {
cout << "错误:无法加载图像,请检查路径是否正确。" << endl;
return - 1 ;
}
// 转换为灰度图像
Mat gray;
cvtColor( image, gray, COLOR_BGR2GRAY) ;
// 二值化
Mat binary;
threshold( gray, binary, 0 , 255 , THRESH_BINARY_INV + THRESH_OTSU) ;
// 定义核
Mat kernel = getStructuringElement( MORPH_RECT, Size( 5 , 5 ) ) ;
// 开运算(去除噪声)
Mat opened;
morphologyEx( binary, opened, MORPH_OPEN, kernel) ;
// 闭运算(填充孔洞)
Mat closed;
morphologyEx( opened, closed, MORPH_CLOSE, kernel) ;
// 显示结果
imshow( "Original Binary" , binary) ;
imshow( "Opened Image" , opened) ;
imshow( "Closed Image" , closed) ;
waitKey( 0 ) ;
return 0 ;
}
直方图处理
直方图处理用于分析图像的像素分布,常见的操作包括直方图均衡化、直方图匹配等。
实例
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( ) {
// 读取图像
Mat image = imread( "low_contrast.jpg" ) ;
if ( image.empty ( ) ) {
cout << "错误:无法加载图像,请检查路径是否正确。" << endl;
return - 1 ;
}
// 转换为灰度图像
Mat gray;
cvtColor( image, gray, COLOR_BGR2GRAY) ;
// 直方图均衡化
Mat equalized;
equalizeHist( gray, equalized) ;
// 显示结果
imshow( "Original Image" , gray) ;
imshow( "Equalized Image" , equalized) ;
waitKey( 0 ) ;
return 0 ;
}
模板匹配
模板匹配用于在图像中查找与模板相似的区域。
实例
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( ) {
// 读取图像和模板
Mat image = imread( "scene.jpg" ) ;
Mat templ = imread( "template.jpg" ) ;
if ( image.empty ( ) || templ.empty ( ) ) {
cout << "错误:无法加载图像,请检查路径是否正确。" << endl;
return - 1 ;
}
// 模板匹配
Mat result;
matchTemplate( image, templ, result, TM_CCOEFF_NORMED) ;
// 找到最佳匹配位置
double minVal, maxVal;
Point minLoc, maxLoc;
minMaxLoc( result, & minVal, & maxVal, & minLoc, & maxLoc) ;
// 绘制矩形框
rectangle( image, maxLoc, Point( maxLoc.x + templ.cols , maxLoc.y + templ.rows ) , Scalar( 0 , 255 , 0 ) , 2 ) ;
// 显示结果
imshow( "Template Matching" , image) ;
waitKey( 0 ) ;
return 0 ;
}