提供函数DWT()和IDWT(),前者完成任意层次的小波变换,后者完成任意层次的小波逆变换。输入图像要求必须是单通道浮点图像,对图像大小也有要求(1层变换:w,h必须是2的倍数;2层变换:w,h必须是4的倍数;3层变换:w,h必须是8的倍数......),变换后的结果直接保存在输入图像中。
1、函数参数简单,图像指针pImage和变换层数nLayer。
2、一个函数直接完成多层次二维小波变换,尽量减少下标运算,避免不必要的函数调用,以提高执行效率。
3、变换过程中,使用了一个指针数组pData用于保存每行数据的起始位置,pRow和pColumn 用于保存一行和一列临时数据,用于奇偶分离或合并,内存消耗较少
// 二维离散小波变换(单通道浮点图像)
void DWT(IplImage *pImage, int nLayer)
{
// 执行条件
if (pImage)
{
if (pImage->nChannels == 1 &&
pImage->depth == IPL_DEPTH_32F &&
((pImage->width >> nLayer) << nLayer) == pImage->width &&
((pImage->height >> nLayer) << nLayer) == pImage->height)
{
int i, x, y, n;
float fValue = 0;
float fRadius = sqrt(2.0f);
int nWidth = pImage->width;
int nHeight = pImage->height;
int nHalfW = nWidth / 2;
int nHalfH = nHeight / 2;
float **pData = new float*[pImage->height];
float *pRow = new float[pImage->width];
float *pColumn = new float[pImage->height];
for (i = 0; i < pImage->height; i++)
{
pData[i] = (float*) (pImage->imageData + pImage->widthStep * i);
}
// 多层小波变换
for (n = 0; n < nLayer; n++, nWidth /= 2, nHeight /= 2, nHalfW /= 2, nHalfH /= 2)
{
// 水平变换
for (y = 0; y < nHeight; y++)
{
// 奇偶分离
memcpy(pRow, pData[y], sizeof(float) * nWidth);
for (i = 0; i < nHalfW; i++)
{
x = i * 2;
pData[y][i] = pRow[x];
pData[y][nHalfW + i] = pRow[x + 1];
}
// 提升小波变换
for (i = 0; i < nHalfW - 1; i++)
{
fValue = (pData[y][i] + pData[y][i + 1]) / 2;
pData[y][nHalfW + i] -= fValue;
}
fValue = (pData[y][nHalfW - 1] + pData[y][nHalfW - 2]) / 2;
pData[y][nWidth - 1] -= fValue;
fValue = (pData[y][nHalfW] + pData[y][nHalfW + 1]) / 4;
pData[y][0] += fValue;
for (i = 1; i < nHalfW; i++)
{
fValue = (pData[y][nHalfW + i] + pData[y][nHalfW + i - 1]) / 4;
pData[y][i] += fValue;
}
// 频带系数
for (i = 0; i < nHalfW; i++)
{
pData[y][i] *= fRadius;
pData[y][nHalfW + i] /= fRadius;
}
}
// 垂直变换
for (x = 0; x < nWidth; x++)
{
// 奇偶分离
for (i = 0; i < nHalfH; i++)
{
y = i * 2;
pColumn[i] = pData[y][x];
pColumn[nHalfH + i] = pData[y + 1][x];
}
for (i = 0; i < nHeight; i++)
{
pData[i][x] = pColumn[i];
}
// 提升小波变换
for (i = 0; i < nHalfH - 1; i++)
{
fValue = (pData[i][x] + pData[i + 1][x]) / 2;
pData[nHalfH + i][x] -= fValue;
}
fValue = (pData[nHalfH - 1][x] + pData[nHalfH - 2][x]) / 2;
pData[nHeight - 1][x] -= fValue;
fValue = (pData[nHalfH][x] + pData[nHalfH + 1][x]) / 4;
pData[0][x] += fValue;
for (i = 1; i < nHalfH; i++)
{
fValue = (pData[nHalfH + i][x] + pData[nHalfH + i - 1][x]) / 4;
pData[i][x] += fValue;
}
// 频带系数
for (i = 0; i < nHalfH; i++)
{
pData[i][x] *= fRadius;
pData[nHalfH + i][x] /= fRadius;
}
}
}
delete[] pData;
delete[] pRow;
delete[] pColumn;
}
}
}
// 二维离散小波恢复(单通道浮点图像)
void IDWT(IplImage *pImage, int nLayer)
{
// 执行条件
if (pImage)
{
if (pImage->nChannels == 1 &&
pImage->depth == IPL_DEPTH_32F &&
((pImage->width >> nLayer) << nLayer) == pImage->width &&
((pImage->height >> nLayer) << nLayer) == pImage->height)
{
int i, x, y, n;
float fValue = 0;
float fRadius = sqrt(2.0f);
int nWidth = pImage->width >> (nLayer - 1);
int nHeight = pImage->height >> (nLayer - 1);
int nHalfW = nWidth / 2;
int nHalfH = nHeight / 2;
float **pData = new float*[pImage->height];
float *pRow = new float[pImage->width];
float *pColumn = new float[pImage->height];
for (i = 0; i < pImage->height; i++)
{
pData[i] = (float*) (pImage->imageData + pImage->widthStep * i);
}
// 多层小波恢复
for (n = 0; n < nLayer; n++, nWidth *= 2, nHeight *= 2, nHalfW *= 2, nHalfH *= 2) {
// 垂直恢复
for (x = 0; x < nWidth; x++)
{
// 频带系数
for (i = 0; i < nHalfH; i++)
{
pData[i][x] /= fRadius;
pData[nHalfH + i][x] *= fRadius;
}
// 提升小波恢复
fValue = (pData[nHalfH][x] + pData[nHalfH + 1][x]) / 4;
pData[0][x] -= fValue;
for (i = 1; i < nHalfH; i++)
{
fValue = (pData[nHalfH + i][x] + pData[nHalfH + i - 1][x]) / 4;
pData[i][x] -= fValue;
}
for (i = 0; i < nHalfH - 1; i++)
{
fValue = (pData[i][x] + pData[i + 1][x]) / 2;
pData[nHalfH + i][x] += fValue;
}
fValue = (pData[nHalfH - 1][x] + pData[nHalfH - 2][x]) / 2;
pData[nHeight - 1][x] += fValue;
// 奇偶合并
for (i = 0; i < nHalfH; i++)
{
y = i * 2;
pColumn[y] = pData[i][x];
pColumn[y + 1] = pData[nHalfH + i][x];
}
for (i = 0; i < nHeight; i++)
{
pData[i][x] = pColumn[i];
}
}
// 水平恢复
for (y = 0; y < nHeight; y++)
{
// 频带系数
for (i = 0; i < nHalfW; i++)
{
pData[y][i] /= fRadius;
pData[y][nHalfW + i] *= fRadius;
}
// 提升小波恢复
fValue = (pData[y][nHalfW] + pData[y][nHalfW + 1]) / 4;
pData[y][0] -= fValue;
for (i = 1; i < nHalfW; i++)
{
fValue = (pData[y][nHalfW + i] + pData[y][nHalfW + i - 1]) / 4;
pData[y][i] -= fValue;
}
for (i = 0; i < nHalfW - 1; i++)
{
fValue = (pData[y][i] + pData[y][i + 1]) / 2;
pData[y][nHalfW + i] += fValue;
}
fValue = (pData[y][nHalfW - 1] + pData[y][nHalfW - 2]) / 2;
pData[y][nWidth - 1] += fV alue;
// 奇偶合并
for (i = 0; i < nHalfW; i++)
{
x = i * 2;
pRow[x] = pData[y][i];
pRow[x + 1] = pData[y][nHalfW + i];
}
memcpy(pData[y], pRow, sizeof(float) * nWidth);
}
}
delete[] pData;
delete[] pRow;
delete[] pColumn;
}
}
}
上述代码只能对单通道进行变换,并且对图像位深和大小也有要求,还是不太好用。没关系,就这两个函数,可以对任意大小的彩色图像进行任意层次的小波变换,给段代码:
// 小波变换层数
int nLayer = 2;
// 输入彩色图像
IplImage *pSrc = cvLoadImage("Lena.jpg", CV_LOAD_IMAGE_COLOR);
// 计算小波图象大小
CvSize size = cvGetSize(pSrc);
if ((pSrc->width >> nLayer) << nLayer != pSrc->width)
{
size.width = ((pSrc->width >> nLayer) + 1) << nLayer;
}
if ((pSrc->height >> nLayer) << nLayer != pSrc->height)
{
size.height = ((pSrc->height >> nLayer) + 1) << nLayer;
}
// 创建小波图象
IplImage *pWavelet = cvCreateImage(size, IPL_DEPTH_32F, pSrc->nChannels);
if (pWavelet)
{
// 小波图象赋值
cvSetImageROI(pWavelet, cvRect(0, 0, pSrc->width, pSrc->height));
cvConvertScale(pSrc, pWavelet, 1, -128);
cvResetImageROI(pWavelet);
// 彩色图像小波变换
IplImage *pImage = cvCreateImage(cvGetSize(pWavelet), IPL_DEPTH_32F, 1);
if (pImage)
{
for (int i = 1; i <= pWavelet->nChannels; i++)
{
cvSetImageCOI(pWavelet, i);
cvCopy(pWavelet, pImage, NULL);
// 二维离散小波变换
DWT(pImage, nLayer);
// 二维离散小波恢复
// IDWT(pImage, nLayer);
cvCopy(pImage, pWavelet, NULL);
}
cvSetImageCOI(pWavelet, 0);
cvReleaseImage(&pImage);
}
// 小波变换图象
cvSetImageROI(pWavelet, cvRect(0, 0, pSrc->width, pSrc->height));
cvConvertScale(pWavelet, pSrc, 1, 128);
cvResetImageROI(pWavelet); // 本行代码有点多余,但有利用养成良好的编程习惯 cvReleaseImage(&pWavelet);
}
// 显示图像pSrc
// ...
cvReleaseImage(&pSrc);
#include "stdafx.h" #include "mymfc.h" #include "mymfcDlg.h" #include "afxdialogex.h" #include
CmymfcDlg::CmymfcDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CmymfcDlg::IDD, pParent) , TheImage(NULL) , rePath(_T("")) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CmymfcDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CmymfcDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_ReadImg, &CmymfcDlg::OnBnClickedReadimg) ON_BN_CLICKED(IDC_EdgeDetect, &CmymfcDlg::OnBnClickedEdgedetect) ON_BN_CLICKED(IDC_Refresh, &CmymfcDlg::OnBnClickedRefresh) ON_BN_CLICKED(IDC_GrayProcess, &CmymfcDlg::OnBnClickedGrayprocess) ON_BN_CLICKED(IDC_Sobel, &CmymfcDlg::OnBnClickedSobel) ON_BN_CLICKED(IDC_Laplace, &CmymfcDlg::OnBnClickedLaplace) ON_BN_CLICKED(IDC_FFT2, &CmymfcDlg::OnBnClickedFft2) ON_BN_CLICKED(IDC_CImage, &CmymfcDlg::OnBnClickedCimage) ON_BN_CLICKED(IDC_Mirror, &CmymfcDlg::OnBnClickedMirror) ON_BN_CLICKED(IDC_CColor, &CmymfcDlg::OnBnClickedCcolor) ON_BN_CLICKED(IDC_MedianBlur, &CmymfcDlg::OnBnClickedMedianblur) ON_BN_CLICKED(IDC_Gaussian, &CmymfcDlg::OnBnClickedGaussian) ON_BN_CLICKED(IDC_BothSide, &CmymfcDlg::OnBnClickedBothside) ON_BN_CLICKED(IDC_Equally, &CmymfcDlg::OnBnClickedEqually) ON_BN_CLICKED(IDC_Corrosion, &CmymfcDlg::OnBnClickedCorrosion) ON_BN_CLICKED(IDC_Dilate, &CmymfcDlg::OnBnClickedDilate) END_MESSAGE_MAP() // CmymfcDlg 消息处理程序 BOOL CmymfcDlg::OnInitDialog() { CDialogEx::OnInitDialog();
OpenCV成长之路(8):直线、轮廓的提取与描述 分类:OpenCV成长之路2014-01-04 18:35 689人阅读评论(0) 收藏举报 直线、轮廓的提取与描述基于内容的图像分析的重点是提取出图像中具有代表性的特征,而线条、轮廓、块往往是最能体现特征的几个元素,这篇文章就针对于这几个重要的图像特征,研究它们在OpenCV中的用法,以及做一些简单的基础应用。 一、Canny检测轮廓 在上一篇文章中有提到sobel边缘检测,并重写了soble的C++代码让其与matlab中算法效果一致,而soble边缘检测是基于单一阈值的,我们不能兼顾到低阈值的丰富边缘和高阈值时的边缘缺失这两个问题。而canny算子则很好的弥补了这一不足,从目前看来,canny边缘检测在做图像轮廓提取方面是最优秀的边缘检测算法。 canny边缘检测采用双阈值值法,高阈值用来检测图像中重要的、显著的线条、轮廓等,而低阈值用来保证不丢失细节部分,低阈值检测出来的边缘更丰富,但是很多边缘并不是我们关心的。最后采用一种查找算法,将低阈值中与高阈值的边缘有重叠的线条保留,其他的线条都删除。 本篇文章中不对canny的算法原理作进一步说明,稍后会在图像处理算法相关的文章中详细介绍。 下面我们用OpenCV中的Canny函数来检测图像边缘 1.int main() 2.{ 3. Mat I=imread("../cat.png"); 4. cvtColor(I,I,CV_BGR2GRAY); 5. 6. Mat contours; 7. Canny(I,contours,125,350); 8. threshold(contours,contours,128,255,THRESH_BINARY); 9. 10. namedWindow("Canny"); 11. imshow("Canny",contours);
第28卷第1期计算机工程与设计2007年1月V01.28No.1ComputerEngineeringandDesignJan.2007 基于OpenCV的摄像机标定 尹文生,罗瑜林,李世其 (华中科技大学机械科学与工程学院,湖北武汉430074) 摘要:以增强现实系统中摄像机标定技术为研究对象,分析了开放计算机视觉函数库OpenCV中的摄像机模型,特别充分考虑了透镜的径向畸变和切向畸变影响及求解方法,给出了基于OpenCV的摄像机标定算法。该算法充分发挥了OpenCV的函数库功能,提高了标定精度和计算效率,具有良好的跨平台移植性,可以满足增强现实和其它计算机视觉系统的需要。 关键词:计算机视觉;增强现实;摄像机模型;透镜畸变;摄像机标定 中图法分类号:TP391文献标识码:A文章编号:1000.7024(2007)01—0197.03 CameracalibrationbasedonOpenCV YINWel"1。sheng,LUOYu.1in,LIShi—qi (SchoolofMechanicalScienceandEngineering,HuazhongUniversityofScienceandTechnology,Wuhan430074,China)Abstract:Fortheapplicationsoftechnologyofcameracalibrationtoaugustreality,thecameramodelinOpenCV(opensourcecomputervisionlibrary)isdiscussed,especiallyontheinfluencesandsolvingmethodsoflensradialdistortionandtangentialdistortion,andanarithmeticofcameracalibrationbasedonOpenCVisgiven.Thisarithmeticmakesuseofthefunctionsofthelibraryeffectively,improvesprecisionandefficiencyofcomputation,andhasagoodpropertyfortheapplicationtomulti-platform.Itcanmeettheneedsofaugustrealityandothercomputervisionsystems. Keywords:computervision;augustreality;cameramodel;lensdistortion;cameracalibration 0引言 摄像机标定,是指建立摄像机成像几何模型,描述空间坐标系中物体点同它在图像平面上像点之间对应关系的过程。摄像机标定的目的就是确定几何模型参数即摄像机参数“1。摄像机标定是计算机视觉应用中的关键技术,在增强现实系统中也必须采用摄像机标定技术实现图像的注册眨”。摄像机标定技术在立体视觉研究中占有非常重要的地位。一个完整的立体视觉系统通常可分为图像获取、摄像机标定、特征提取、立体匹配、深度确定及内插等6大部分“1。精确标定摄像机内外参数不仅可以直接提高测量精度,而且可以为后继的立体图像匹配与三维重建奠定良好的基础。一】。 目前通常采用的标定方法是基于“两步法圳””的传统摄像机标定方法,该方法比主动视觉摄像机标定方法和摄像机自标定方法标定精度高,而且标定过程简单,经过多年的研究已经发展得比较成熟,鲁棒性高。OpenCV(Intel。opensourcecomputervisionlibrary)是Intel。开放计算机视觉函数库,它由一系列C函数和少量C++类构成,实现了图像处理和计算机视觉方面的很多通用算法,具备强大的图像和矩阵运算能力。该函数库中实现的摄像机标定方法采用的是文献[11]中的两步标定方法,而且在2005年7月最新发布的beta5版本中,不只完全重写了摄像机标定函数,而且引入了文献[12】中的自动寻找角点的方法,进一步提高了标定的智能化程度,用户只需导入用于标定的图片,整个标定过程无需人工的介入。OpenCV中的摄像机标定模块为用户提供了良好的接口,同时支持MS.Windows、Linux平台,有效地提高了开发效率,并且执行速度快,具有良好的跨平台移植性,因此可以很好地应用于工程实际当中。 l标定原理 1.1摄像机模型 摄像机标定首先要选择合适的摄像机模型,确定内外部参数。OpenCV标定算法中的摄像机模型以针孔模型(pin—holemodel)为基础,引入透镜的径向畸变和切向畸变,该模型相比于只引入一阶径向畸变的Tasi模型和针孔模型更加真实地反映了透镜实际的畸变情况m1。在该模型中,将空间点P在世界坐标系中的坐标值呱,K,乙)变换为图像平面上像素坐标系中坐标值(“,v)的过程可分解为下述的4步变换”1: 收稿日期:2005-12?06E-marl:wsyin@mail.hust.edu.cn 基金项目:国家民用航天科研专项计划基金项目(科工技[2004]1530)。 作者简介:尹文生(1963一),男,湖南常宁人,博士,副教授,研究方向为智能CAD、虚拟现实技术、机器人遥操作系统;罗瑜林(1981一),男,江西吉安人,硕士研究生,研究方向为机器人遥操作系统、机器视觉;李世其(1965一),男,江西吉安人,博士,教授,研究方向为CAD/CAE、虚拟现实技术、机器人遥操作系统。 一197— 万方数据
目录 1 梯度、边缘和角点 1.1 Sobel 1.2 Laplace 1.3 Canny 1.4 PreCornerDetect 1.5 CornerEigenValsAndVecs 1.6 CornerMinEigenVal 1.7 CornerHarris 1.8 FindCornerSubPix 1.9 GoodFeaturesToTrack 2 采样、插值和几何变换 2.1 InitLineIterator 2.2 SampleLine 2.3 GetRectSubPix 2.4 GetQuadrangleSubPix 2.5 Resize 2.6 WarpAffine 2.7 GetAffineTransform 2.8 2DRotationMatrix 2.9 WarpPerspective 2.10 WarpPerspectiveQMatrix 2.11 GetPerspectiveTransform 2.12 Remap 2.13 LogPolar 3 形态学操作 3.1 CreateStructuringElementEx 3.2 ReleaseStructuringElement 3.3 Erode 3.4 Dilate 3.5 MorphologyEx 4 滤波器与色彩空间变换 4.1 Smooth 4.2 Filter2D 4.3 CopyMakeBorder 4.4 Integral 4.5 CvtColor 4.6 Threshold 4.7 AdaptiveThreshold 5 金字塔及其应用 5.1 PyrDown 5.2 PyrUp 6 连接部件 6.1 CvConnectedComp
/. #include "stdafx.h" #include "mymfc.h" #include "mymfcDlg.h" #include "afxdialogex.h" #include
CmymfcDlg::CmymfcDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CmymfcDlg::IDD, pParent) , TheImage(NULL) , rePath(_T("")) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CmymfcDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CmymfcDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_ReadImg, &CmymfcDlg::OnBnClickedReadimg) ON_BN_CLICKED(IDC_EdgeDetect, &CmymfcDlg::OnBnClickedEdgedetect) ON_BN_CLICKED(IDC_Refresh, &CmymfcDlg::OnBnClickedRefresh) ON_BN_CLICKED(IDC_GrayProcess, &CmymfcDlg::OnBnClickedGrayprocess) ON_BN_CLICKED(IDC_Sobel, &CmymfcDlg::OnBnClickedSobel) ON_BN_CLICKED(IDC_Laplace, &CmymfcDlg::OnBnClickedLaplace) ON_BN_CLICKED(IDC_FFT2, &CmymfcDlg::OnBnClickedFft2) ON_BN_CLICKED(IDC_CImage, &CmymfcDlg::OnBnClickedCimage) ON_BN_CLICKED(IDC_Mirror, &CmymfcDlg::OnBnClickedMirror) ON_BN_CLICKED(IDC_CColor, &CmymfcDlg::OnBnClickedCcolor) ON_BN_CLICKED(IDC_MedianBlur, &CmymfcDlg::OnBnClickedMedianblur) ON_BN_CLICKED(IDC_Gaussian, &CmymfcDlg::OnBnClickedGaussian) ON_BN_CLICKED(IDC_BothSide, &CmymfcDlg::OnBnClickedBothside) ON_BN_CLICKED(IDC_Equally, &CmymfcDlg::OnBnClickedEqually) ON_BN_CLICKED(IDC_Corrosion, &CmymfcDlg::OnBnClickedCorrosion) ON_BN_CLICKED(IDC_Dilate, &CmymfcDlg::OnBnClickedDilate) END_MESSAGE_MAP() // CmymfcDlg 消息处理程序 BOOL CmymfcDlg::OnInitDialog() { CDialogEx::OnInitDialog();
*#include "stdafx.h" #include "cv.h" #include "highgui.h" using namespace cv; using namespace std; //标示符的可见范围 CvPoint2D32f GetCPoint(IplImage* imageFg,int maxX); void FitEllipseBlob(IplImage* imageFg); int main( int argc, char** argv ) { IplImage* pImg; //声明IplImage指针 //载入图像 pImg = cvLoadImage( "C:\\Users\\BB\Desktop\\bec\\OPENCV椭圆拟合定位椭圆中心点以及重心法定位程序\\OPENCV椭圆拟合定位椭圆中心点以及重心法定位程序\\特征中心点提取误差分析\\image.bmp", 1);//[[此处的argc==2是否需要改成argc==1?我改了之后才能运行成功。求大牛解惑]] // wmzzzz : 在"属性"|"debug"|里的command arguments 里加入参数(一个路径:要打开的文件路径) 这时argc==2 就合理了...可以试试多加几个 int pointX = 0; for (int i=0;i<19;i++) { pointX=60*i+30; cvEllipse(pImg,cvPoint(pointX,80),cvSize(19,20),-200,0,360,CV_RGB(255,255,255),-1,CV _AA,0); } IplImage* m_imageGray = cvCreateImage(cvSize(pImg->width,pImg->height),IPL_DEPTH_8U,1); IplImage* m_imageBw = cvCreateImage(cvSize(pImg->width,pImg->height),IPL_DEPTH_8U,1); cvCvtColor(pImg,m_imageGray,CV_RGB2GRAY); cvThreshold(m_imageGray,m_imageBw,128,255,CV_THRESH_BINARY); CvPoint2D32f pointXX; float XXX,YYY; for (int i = 0;i<19;i++) {
// cvCalib.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include
基于opencv 对图像的预处理 1.问题描述 本次设计是基于opencv 结合c++语言实现的对图像的预处理,opencv 是用于开发实时的图像处理、计算机视觉及模式识别程序;其中图像的预处理也就是利用opencv 对图像进行简单的编辑操作;例如对图像的对比度、亮度、饱和度进行调节,同时还可以对图像进行缩放和旋转,这些都是图像预处理简单的处理方法;首先通过opencv 加载一幅原型图像,显示出来;设置五个滑动控制按钮,当拖动按钮时,对比度、亮度、饱和度的大小也会随之改变,也可以通过同样的方式调节缩放的比例和旋转的角度,来控制图像,对图像进行处理,显示出符合调节要求的图像,进行对比观察他们的之间的变化。 2.模块划分 此次设计的模块分为五个模块,滑动控制模块、对比度和亮度调节模块、饱和度调节模块、缩放调节模块、旋转调节模块,他们之间的关系如下所示: 图一、各个模块关系图 调用 调用 调用 调用 滑动控制模块 对比度和亮度调节模块 饱和度调节模块 缩放调节模块 旋转调节模块
滑动控制模块处于主函数之中,是整个设计的核心部分,通过createTrackbar创建五个滑动控制按钮并且调用每个模块实现对图像相应的调节。 3.算法设计 (1)滑动控制: 滑动控制是整个设计的核心部分,通过创建滑动控制按钮调节大小来改变相应的数据,进行调用函数实现对图像的编辑,滑动控制是利用createTrackbar(),函数中包括了滑动控制的名称,滑动控制显示在什么窗口上,滑动变量的地址和它调节的最大围,以及每个控制按钮应该调用什么函数实现什么功能; (2)对比度和亮度的调节: 对比度和亮度的调节的原理是依照线性理论,它的公式如下所示:g(x)=a* f(x) +b,其中f(x)表示源图像的像素,g(x)表示输出图像的像素,参数a(需要满足a>0)被称为增益(gain),常常被用来控制图像的对比度,参数b通常被称为偏置(bias),常常被用来控制图像的亮度; (3)饱和度的调节: 饱和度调节利用cvCvtColor( src_image, dst_image, CV_BGR2HSV )将RGB 颜色空间转换为HSV颜色空间,其中“H=Hue”表示色调,“S=Saturation”表示饱和度,“V=Value ”表示纯度;所以饱和度的调节只需要调节S的大小,H 和V的值不需要做任何的改变; (4)旋转的调节: 旋转是以某参考点为圆心,将图像的个点(x,y)围绕圆心转动一个逆时针角度θ,变为新的坐标(x1,y1),x1=rcos(α+θ),y1=rsin(α+θ),其中r是图像的极径,α是图像与水平的坐标的角度的大小; (5)缩放的调节: 首先得到源图像的宽度x和高度y,变换后新的图像的宽度和高度分别为x1和y1,x1=x*f,y1=y*f,其中f是缩放因子; 4.函数功能描述 (1)主函数main()用来设置滑动控制按钮,当鼠标拖动按钮可以得到相应的数据大小,实现手动控制的功能,当鼠标拖动对比度和亮度调节是,主函数调用
// // The full "Square Detector" program. // It loads several images subsequentally and tries to find squares in // each image // #ifdef _CH_ #pragma package
本程序主要实现的是车牌的定位与检测 主要是利用申继龙论文里面的方法 1、采集得到的图像 2、把RGB图像转换成HSI彩色图像 3、利用设定的H、S阈值得到二值图像 4、对二值图像水平投影获得候选区域 5、对候选区域的HSI图像边缘检测 */ #include "stdafx.h" #include "opencv2/opencv.hpp" #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/features2d/features2d.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/calib3d/calib3d.hpp" #include "opencv2/nonfree/nonfree.hpp" #include "opencv2/nonfree/features2d.hpp" #include "opencv2/imgproc/imgproc_c.h" #include "opencv2/legacy/legacy.hpp" #include "opencv2/legacy/compat.hpp" #include
?什么是OpenCV ?开源C/C++计算机视觉库. ?面向实时应用进行优化. ?跨操作系统/硬件/窗口管理器. ?通用图像/视频载入、存储和获取. ?由中、高层API构成. ?为Intel?公司的Integrated Performance Primitives (IPP) 提供了透明接口. ?特性: ?图像数据操作(分配,释放, 复制, 设定, 转换). ?图像与视频I/O (基于文件/摄像头输入, 图像/视频文件输出). ?矩阵与向量操作与线性代数计算(相乘, 求解, 特征值, 奇异值分解SVD). ?各种动态数据结构(列表, 队列, 集, 树, 图). ?基本图像处理(滤波, 边缘检测, 角点检测, 采样与插值, 色彩转换, 形态操作, 直方图, 图像金字塔). ?结构分析(连接成分, 轮廓处理, 距离转换, 模板匹配, Hough转换, 多边形近似, 线性拟合, 椭圆拟合, Delaunay三角化). ?摄像头标定 (寻找并跟踪标定模板, 标定, 基础矩阵估计, homography估计, 立体匹配). ?动作分析(光流, 动作分割, 跟踪). ?对象辨识 (特征方法, 隐马可夫链模型HMM). ?基本GUI(显示图像/视频, 键盘鼠标操作, 滚动条). ?图像标识 (直线, 圆锥, 多边形, 文本绘图) ?OpenCV 模块: ?cv - OpenCV 主要函数. ?cvaux - 辅助(实验性) OpenCV 函数. ?cxcore - 数据结构与线性代数算法. ?highgui - GUI函数. 资料链接 ?参考手册: ?
万方数据
万方数据
万方数据
2010年6月中同制造、Ip信息化第39卷第11期 图2汽车车身部分原始图像1图4基于本文算法的处理结果1 图3汽车车身部分原始图像2图5基于本文算法的处理结果2 方便,具有广阔的应用前景。本文针对灰度分布不 均匀的图像,首先,通过对图像开窗后进行局部灰参考文献: 碱∞∞Pan肌AnalysisandM8ch妇1n‘e11igence,1986,度变换来改进边缘检测的效果,对窗口交界处再开hiCannyJA.Ccmaputationalapproachtoedgedetection[J].IEEE 设几个很小的窗口实现拼接来去除窗口交界处的 皇假边缘;其次,詈用自适璺阈值的改进型Canny[2]8章(6毓)晋:67.图9-像69处8理.与分析[M】.|匕京:清华大学出版社,1999:算法动态地随图像梯度幅值变化而变化。通过试懈一枷 验证明,本文的方法对于不同噪声干扰和光照背景[3]杨枝灵,王开.WLsualc++数字图像获取、处理及实践应下的图像,能够获得较好的处理效果,其抗噪性能用[M].北京:人民邮电出版社,2003:553—572. 好,定位精度高。利用该算法对汽车图像进行边缘[4]刑果?戚文芽,李萍,等?灰度图像的自适应边缘检测 [J].计算机工程与应用,2007,43(5):63—66? 检测,检测出的汽车边缘连续、清晰。 ApplicationofOpenCV——basedEdgeDetectionAgorithm intheVehicle——bodyDimensionDetection CHENWei—li,TANG/-Ion,GENGYah—biao (NorthwesternPolytechnicalUniversity,ShaanxiXi’aJl,710072,China) Abstract:Itmainlyintroducesthesolutiontoimprovetheefficiencyoftheedgedetection,whichcombinesthe detectionalgorithmofthestatisticalimagewindowcalculationwiththeenhancedCannyedgedetectionalgo—rithm.ItusesOpenCVdatabase雒basicfunctionlibraryandappliesthisagorithmtothevehicle—bodydi—mensiondetection.Thetestresultsshowthattheprocessingofedgedetectionismoreeffectiveandquicker.Keywords:Edge——detection;ImageProcess;Vehicle——bodyDimension 万方数据
38562009,30(16)计算机工程与设计Computer Engineering and Design 0引言 机器视觉的基本任务之一是从摄像机获取的图像信息出发计算三维空间中物体的几何信息,并由此重建和识别物体,而空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系是由摄像机成像的几何模型决定的,这些几何模型参数就是摄像机参数。在大多数条件下,这些参数必须通过实验与计算才能得到,这个过程称为摄像机标定(或定标)。标定过程就是确定摄像机的几何和光学参数,摄像机相对于世界坐标系的方位。标定精度的大小,直接影响着机器视觉的精度。迄今为止,对于摄像机标定问题已提出了很多方法,摄像机标定的理论问题已得到较好的解决[1-5]。对摄像机标定的研究来说,当前的研究工作应该集中在如何针对具体的实际应用问题,采用特定的简便、实用、快速、准确的标定方法。 OpenCV是Intel公司资助的开源计算机视觉(open source computer vision)库,由一系列C函数和少量C++类构成,可实现图像处理和计算机视觉方面的很多通用算法。OpenCV有以下特点: (1)开放C源码; (2)基于Intel处理器指令集开发的优化代码; (3)统一的结构和功能定义; (4)强大的图像和矩阵运算能力; (5)方便灵活的用户接口; (6)同时支持Windows和Linux平台。 作为一个基本的计算机视觉、图像处理和模式识别的开源项目,OpenCV可以直接应用于很多领域,是二次开发的理想工具。目前,OpenCV的最新版本是2006年发布的OpenCV 1.0版,它加入了对GCC4.X和Visual https://www.sodocs.net/doc/6f6443720.html,2005的支持。 1摄像机标定原理 1.1世界、摄像机与图像坐标系 摄像机标定中有3个不同层次的坐标系统:世界坐标系、摄像机坐标系和图像坐标系(图像像素坐标系和图像物理坐标系)。 如图1所示,在图像上定义直角坐标系 开发与应用
#include "cv.h" #include "highgui.h" #include
openCV——几个实用函数 2010年12月20日星期一 09:18 1. cvSmooth:各种方法的图像平滑 void cvSmooth( const CvArr* src, CvArr* dst, int smoothtype=CV_GAUSSIAN, int param1=3, int param2=0, double param3=0 ); src 输入图像. dst 输出图像. smoothtype 平滑方法: . CV_BLUR_NO_SCALE (简单不带尺度变换的模糊) - 对每个象素的param1×param2 领域求和。如果邻域大小是变化的,可以事先利用函数cvIntegral 计算积分图像。 . CV_BLUR (simple blur) - 对每个象素param1×param2邻域求和并做尺度变换 1/(param1.param2). . CV_GAUSSIAN (gaussian blur) - 对图像进行核大小为 param1×param2 的高斯卷积 . CV_MEDIAN (median blur) - 对图像进行核大小为 param1×param1 的中值滤波 (i.e. 邻域是方的). . CV_BILATERAL (双向滤波) - 应用双向 3x3 滤波,彩色 sigma=param1,空间 sigma=param2. 平滑操作的第一个参数. param2 平滑操作的第二个参数. 对于简单/非尺度变换的高斯模糊的情况,如果 param2的值为零,则表示其被设定为param1。 param3
对应高斯参数的 Gaussian sigma (标准差). 如果为零,则标准差由下面的核尺寸计算: sigma = (n/2 - 1)*0.3 + 0.8, 其中 n=param1 对应水平核, n=param2 对应垂直核. 对小的卷积核 (3×3 to 7×7) 使用如上公式所示的标准 sigma 速度会快。如果 param3 不为零,而 param1 和 param2 为零,则核大小有sigma 计算 (以保证足够精确的操作). 函数 cvSmooth 可使用上面任何一种方法平滑图像。每一种方法都有自己的特点以及局限。 没有缩放的图像平滑仅支持单通道图像,并且支持8位到16位的转换(与cvSobel和cvaplace相似)和32位浮点数到32位浮点数的变换格式。 简单模糊和高斯模糊支持 1- 或 3-通道, 8-比特和 32-比特浮点图像。这两种方法可以(in-place)方式处理图像。 中值和双向滤波工作于 1- 或 3-通道, 8-位图像,但是不能以 in-place 方式处理图像. 2.IplImage结构 由于OpenCV主要针对的是计算机视觉方面的处理,因此在函数库中,最重要的结构体是IplImage结构。IplImage结构来源于Intel的另外一个函数库Intel Image Processing Library (IPL),该函数库主要是针对图像处理。IplImage结构具体定义如下: typedef struct _IplImage { int nSize; /* IplImage大小 */ int ID; /* 版本 (=0)*/