OpenCV基础
threshold函数的使用
https://blog.csdn.net/u012566751/article/details/77046445
图像的二值化就是将图像上的像素点的灰度值设置为0或255,这样将使整个图像呈现出明显的黑白效果。在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。OpenCV中提供了函数cv::threshold();
距离变换distanceTransform应用——查找物体质心&&细化字符轮廓
https://www.cnblogs.com/mtcnn/p/9411967.html
distanceTransform方法的功能:
用于计算图像中每一个非零点距离离自己最近的零点的距离,distanceTransform的第二个Mat矩阵参数dst保存了每一个点与最近的零点的距离信息,图像上越亮的点,代表了离零点的距离越远。
一、查找物体质心
C++
#include "core/core.hpp"
#include "imgproc/imgproc.hpp"
#include "highgui/highgui.hpp"using namespace cv;int main(int argc,char *argv[])
{float maxValue=0; //定义距离变换矩阵中的最大值Point Pt(0,0);Mat image=imread(argv[1]);Mat imageGray;cvtColor(image,imageGray,CV_RGB2GRAY);imageGray=~imageGray; //取反GaussianBlur(imageGray,imageGray,Size(5,5),2); //滤波threshold(imageGray,imageGray,20,200,CV_THRESH_BINARY); //阈值化 Mat imageThin(imageGray.size(),CV_32FC1); //定义保存距离变换结果的Mat矩阵distanceTransform(imageGray,imageThin,CV_DIST_L2,3); //距离变换Mat distShow;distShow=Mat::zeros(imageGray.size(),CV_8UC1); //定义细化后的字符轮廓for(int i=0;i<imageThin.rows;i++){for(int j=0;j<imageThin.cols;j++){distShow.at<uchar>(i,j)=imageThin.at<float>(i,j);if(imageThin.at<float>(i,j)>maxValue){maxValue=imageThin.at<float>(i,j); //获取距离变换的极大值Pt=Point(j,i); //坐标}}}normalize(distShow,distShow,0,255,CV_MINMAX); //为了显示清晰,做了0~255归一化circle(image,Pt,maxValue,Scalar(0,0,255),3); circle(image,Pt,3,Scalar(0,255,0),3);imshow("Source Image",image);imshow("Thin Image",distShow);waitKey();return 0;
}
1.原始图片:
2.经过距离变换后距离Mat矩阵dst:
为了显示清晰,做了0~255的归一化。可以看到,中心处最亮,说明了中心点距离零点的距离最远,而最远处就可以作为物体的质心。
3.标记质心(绿色点):
二、细化轮廓
C++:
#include "core/core.hpp"
#include "imgproc/imgproc.hpp"
#include "highgui/highgui.hpp"using namespace cv;int main(int argc,char *argv[])
{float maxValue=0; //定义距离变换矩阵中的最大值Mat image=imread(argv[1]);Mat imageGray;cvtColor(image,imageGray,CV_RGB2GRAY);imageGray=~imageGray; //取反GaussianBlur(imageGray,imageGray,Size(5,5),2); //滤波threshold(imageGray,imageGray,20,200,CV_THRESH_BINARY); //阈值imshow("s",imageGray);Mat imageThin(imageGray.size(),CV_32FC1); //定义保存距离变换结果的Mat矩阵distanceTransform(imageGray,imageThin,CV_DIST_L2,3); //距离变换Mat distShow;distShow=Mat::zeros(imageGray.size(),CV_8UC1); //定义细化后的字符轮廓for(int i=0;i<imageThin.rows;i++){for(int j=0;j<imageThin.cols;j++){if(imageThin.at<float>(i,j)>maxValue){maxValue=imageThin.at<float>(i,j); //获取距离变换的极大值}}}for(int i=0;i<imageThin.rows;i++){for(int j=0;j<imageThin.cols;j++){if(imageThin.at<float>(i,j)>maxValue/1.9){distShow.at<uchar>(i,j)=255; //符合距离大于最大值一定比例条件的点设为255}}}imshow("Source Image",image);imshow("Thin Image",distShow);waitKey();return 0;
}
1.原始图像:
2.细化效果:
形态学操作之腐蚀与膨胀
https://blog.csdn.net/qq_42856191/article/details/123663533
一、腐蚀(erosion)
1.1 什么是腐蚀
简单来说,腐蚀就是把图像中的物体变小了!(用背景去侵蚀前景)
腐蚀的工作过程如下图所示,A是一个集合,B是一个结构单元,我们使用B去对集合A进行腐蚀,腐蚀过程如C所示,在腐蚀过程中,结构单元必须全部位于集合A中才能进行腐蚀操作,最终得到的结果即为D所示。
Python:
import cv2
import numpy as npori = cv2.imread(r"C:\Users\Lenovo\Desktop\original.jpg") # 读取图像kernel1 = np.ones((3, 3), np.uint8) # 3个不同尺度的腐蚀单元
kernel2 = np.ones((5, 5), np.uint8)
kernel3 = np.ones((7, 7), np.uint8)erosion1 = cv2.erode(ori, kernel1) # 腐蚀函数
erosion2 = cv2.erode(ori, kernel2)
erosion3 = cv2.erode(ori, kernel3)cv2.imshow("original", ori)
cv2.imshow("erosion1", erosion1)
cv2.imshow("erosion2", erosion2)
cv2.imshow("erosion3", erosion3)cv2.imwrite(r'C:\Users\Lenovo\Desktop\erosion1.jpg', erosion1)
cv2.imwrite(r'C:\Users\Lenovo\Desktop\erosion2.jpg', erosion2)
cv2.imwrite(r'C:\Users\Lenovo\Desktop\erosion3.jpg', erosion3)cv2.waitKey()
下面展示的是程序得到的结果图,由图可知,腐蚀能对图像中的毛刺进行去除,但这也与腐蚀单元的大小有关,3 × 3 3×33×3大小的核去除效果不如5 × 5 5×55×5与7 × 7 7×77×7,此外7 × 7 7×77×7的核使得图像变得更加细小。
二、膨胀(dilation)
2.1 什么是膨胀
简单来说,膨胀就是把图像中的物体变大了!(对前景进行膨胀)
膨胀的工作过程如下图所示,A是一个集合,B是一个结构单元,我们使用B去对集合A进行膨胀,膨胀过程如C所示,在膨胀过程中,结构单元只要有一个位于集合A中就能进行膨胀操作,最终得到的结果即为D所示。
Python:
import cv2
import numpy as npori = cv2.imread(r"C:\Users\Lenovo\Desktop\original.jpg") # 读取图像kernel1 = np.ones((3, 3), np.uint8) # 3个不同尺度的腐蚀单元
kernel2 = np.ones((5, 5), np.uint8)
kernel3 = np.ones((9, 9), np.uint8)dilation1 = cv2.dilate(ori, kernel1) # 膨胀函数
dilation2 = cv2.dilate(ori, kernel2)
dilation3 = cv2.dilate(ori, kernel3)cv2.imshow("original", ori)
cv2.imshow("dilation1", dilation1)
cv2.imshow("dilation2", dilation2)
cv2.imshow("dilation3", dilation3)cv2.imwrite(r'C:\Users\Lenovo\Desktop\dilation1.jpg', dilation1)
cv2.imwrite(r'C:\Users\Lenovo\Desktop\dilation2.jpg', dilation2)
cv2.imwrite(r'C:\Users\Lenovo\Desktop\dilation3.jpg', dilation3)cv2.waitKey()
下面展示的是程序得到的结果图,由图可知,膨胀能对图像中的物体进行扩张,但这也与膨胀单元的大小有关,越大的膨胀核使得图像扩张区域更大。
形态学操作之开运算与闭运算
https://blog.csdn.net/qq_42856191/article/details/123670455
一、开运算
1.1 什么是开运算:先腐蚀后膨胀的操作称为开运算。
1.2作用:消除细小物体、在窄区域分离物体、平滑大物体边界等。
二、闭运算
2.1 什么是闭运算:先膨胀后腐蚀的操作称为闭运算。
2.2作用:填充物体空洞、消除噪声、连接邻近物体、平滑边界等。
图像分割 – 距离变换与分水岭算法(硬币检测、扑克牌检测、车道检测)
https://blog.csdn.net/great_yzl/article/details/119831771
以上述引用中的硬币检测为例子的分割过程:
1.将RGB图片转换为灰度图
2.去噪
开运算:先侵蚀后膨胀。会将两个物体之间可能存在的粘连噪点过滤,并将前景物体扩大。
3.确定背景区域
对图片进行膨胀操作,将前景扩大,背景也会随之减小。那么此时对象>原对象,此时背景 < 原背景,那么此时的背景自然可以确定为原背景的一部分。(离对象中心很远的是背景)
4.确定前景区域
原理:距离变换,在二值图中把对象缩小,得到的就是原图的一部分,可以确定为前景。
这种距离变换可以将前景中的不同实例分离,距离变换后得到前景物体不同灰度值的像素,通过threshold函数选定一个阈值来缩小前景物体中每个的大小,从而达到将不同实例分离的效果。(不分离的话,可以不用距离变换,只用腐蚀就够了)
下图分别为img原始图片、opening膨胀后的图片、sure_fg距离变换后经过threshold阈值操作获得的确定前景实例