OpenCV学习小记(1)
1.反转图像
函数:cv::flip()
void flip(InputArray src, OutputArray dst, int flipCode);
参数fipCode: 整数,水平发转;0垂直反转;负数,水平垂直均反转。 2.sobel边缘检测
函数:cv::sobel()
例程:
//从文件中读入图像
const char* imagename = "lena.BMP";
Mat img = imread(imagename);
if(img.empty()) //如果读入图像失败
{
fprintf(stderr, "Can not load image %s\n", imagename);
return -1;
}
namedWindow("original image");
imshow("original image",img);
//Mat result;
//flip(img, result, -1); //反转图像
Mat sobelX, sobelY, sobel;
Sobel(img, sobelX, CV_16S, 1, 0);
Sobel(img, sobelY, CV_16S, 0, 1);
sobel = abs(sobelX) + abs(sobelY);
//搜索sobel极大值
double sobmin, sobmax;
minMaxLoc(sobel, &sobmin, &sobmax);
//变换为8位图像
//sobelImage = -alpha*sobel + 255
Mat sobelImage;
sobel.convertTo(sobelImage, CV_8U, -255./sobmax, 255);
namedWindow("sobelImage");
imshow("sobelImage", sobelImage);
Mat sobelThresholded;
double threadVal = 200;
threshold(sobelImage, sobelThresholded, threadVal, 255, THRESH_BINARY);
namedWindow("sobelThresholded");
imshow("sobelThresholded", sobelThresholded);
3. 读取单通道灰度图像
Mat img = imread("lena.bmp", 0);
imshow("lena", img);
建立的img是单通道的。
4. 中值滤波
CvImgProc cvImgProc;
Mat img = imread("lena.bmp", 0); //读取图像
namedWindow("lena", CV_WINDOW_AUTOSIZE);
imshow("lena", img);
Mat saltImg = img.clone(); //复制图像
cvImgProc.salt(saltImg, 1000); //添加椒盐噪声
namedWindow("saltlena", CV_WINDOW_AUTOSIZE);
imshow("saltlena", saltImg);
Mat blurImg;
medianBlur(saltImg, blurImg, 3); //5*5中值滤波
namedWindow("blurImg", CV_WINDOW_AUTOSIZE);
imshow("blurImg", blurImg);
5. canny边缘检测
Mat img = imread("lena.bmp", 0); //读取图像
namedWindow("lena", CV_WINDOW_AUTOSIZE);
imshow("lena", img);
Mat contours;
Canny(img, contours, 125, 350); //canny边缘检测
namedWindow("contours", CV_WINDOW_AUTOSIZE);
imshow("contours", contours);
Mat contoursInv;
threshold(contours, contoursInv, 128, 255, THRESH_BINARY_INV); //反转边缘图像
namedWindow("contoursInv", CV_WINDOW_AUTOSIZE);
imshow("contoursInv", contoursInv);
6. 腐蚀操作
原理:腐蚀替换当前像素位像素集合中找到的最小像素值。
//读取输入图像
Mat image = imread("binary.bmp");
namedWindow("binary");
imshow("binary", image);
//腐蚀图像
Mat eroded; //目标图像
//使用默认的方形结构元素(等价于以下注释掉的代码)
erode(image, eroded, Mat());
//Mat element(3, 3, CV_8U, Scalar(1));
//erode(image, eroded, element);
//显示腐蚀后的图像
namedWindow("Eroded Image");
imshow("Eroded Image", eroded);
7. 膨胀操作
原理:膨胀是替换当前像素位像素集合中找到的最大像素值。
//读取输入图像
Mat image = imread("binary.bmp");
namedWindow("binary");
imshow("binary", image);
//膨胀图像
Mat dilated; //目标图像
//使用默认的方形结构元素(等价于以下注释掉的代码)
dilate(image, dilated, Mat());
//Mat element(3, 3, CV_8U, Scalar(1));
//dilate(image, dilated, element);
//显示膨胀后的图像
namedWindow("Dilated Image");
imshow("Dilated Image", dilated);
还可以进行多次膨胀,只需将执行函数该为:
dilate(image, dilated, Mat(), Point(-1, -1), 3);
8. 图像二值化
CvImgProc cvImgProc;
//读取输入图像
//Mat image = imread("lena.bmp");
IplImage* iplImage = cvLoadImage("lena.bmp");
IplImage* iplImage2 = cvCreateImage(cvSize(512, 512), IPL_DEPTH_8U, 1);
double thresholdVal = cvImgProc.cvThresholdOtsu(iplImage);
printf("thresholdVal = %lf", thresholdVal);
Mat image(iplImage, false);
Mat image3;
threshold(image, image3, thresholdVal, 255, THRESH_BINARY);
namedWindow("binary");
imshow("binary", image3);
得出阈值是127
version 2:
CvImgProc cvImgProc;
//读取输入图像
Mat image = imread("camera.tiff");
Mat image2;
int thresholdVal = cvImgProc.cvOtsu(image);
printf("thresholdVal = %d", thresholdVal);
threshold(image, image2, thresholdVal, 255, THRESH_BINARY);
namedWindow("binary");
imshow("binary", image2);
imwrite("cameraBinary.bmp", image2);
9.闭运算
//读取输入图像
Mat image = imread("lenaBinary.bmp");
Mat element5(3, 3, CV_8U, Scalar(1));
Mat closed;
morphologyEx(image, closed, MORPH_CLOSE, element5);
namedWindow("closed");
imshow("closed", closed);
10.开运算
//读取输入图像
Mat image = imread("lenaBinary.bmp");
Mat element3(3, 3, CV_8U, Scalar(1));
Mat opened;
morphologyEx(image, opened, MORPH_CLOSE, element3);
namedWindow("closed");
imshow("closed", opened);
11.三通道彩色图像转单通道灰度图像
//读取输入图像
Mat image = imread("pepper.bmp");
namedWindow("image");
imshow("image", image);
Mat image2;
cvtColor(image, image2, CV_BGR2GRAY, 1); //尾参:无/0保留通道个数;1单通道;3三通道。
namedWindow("image2");
imshow("image2", image2);
imwrite("pepperGray.bmp", image2);
//读取输入图像
Mat image = imread("lena.bmp");
namedWindow("image");
imshow("image", image);
double minVal, maxVal;
minMaxLoc(image, &minVal, &maxVal);
printf("minVal = %lf\n", minVal);
printf("maxVal = %lf\n", maxVal);
13.角点提取
//读取输入图像
Mat image = imread("calibrateGray.bmp");
namedWindow("image");
imshow("image", image);
//检测角点
Mat cornerStrength;
cornerHarris(image, cornerStrength,
3, //相邻像素的尺寸
3, //滤波器的孔径大小
0.01); //Harris参数
//角点强度的阈值
Mat harrisCorners;
double thresholdVal = 0.0001;
threshold(cornerStrength, harrisCorners, thresholdVal, 255, THRESH_BINARY_INV);
namedWindow("harrisCorners");
imshow("harrisCorners", harrisCorners);
imwrite("calibrateHarris.bmp", harrisCorners);
14.判断图像是否读入成功
//读取输入图像
Mat image = imread("calibrateGray.bmp");
if (!image.data)
{
printf("读取图像失败\n");
}
15. 将unsigned char*(或BYTE*)封装成Mat类型
version 1
int width = 0;
int height = 0;
int lineByte = 0;
BYTE* imData = rdWtIm.Read8bitbmp("cam1FstImArSptImage.bmp", &width, &height, &lineByte);
printf("width = %d\n", width);
printf("height = %d\n", height);
printf("lineByte = %d\n", lineByte);
Mat iMat(height, width, CV_8UC1, imData, lineByte);
namedWindow("lena");
imshow("lena", iMat);
version 2
RdWtIm rdWtIm;
int width = 0;
int height = 0;
int lineByte = 0;
BYTE* imData = rdWtIm.Read8bitbmp("lena.bmp", &width, &height, &lineByte); //cam1FstImArSptImage
printf("width = %d\n", width);
printf("height = %d\n", height);
printf("lineByte = %d\n", lineByte);
//Scalar scal = 0;
Mat iMat(height, width, CV_8UC1, Scalar(0));
iMat.step = lineByte;
iMat.data = imData;
namedWindow("lena");
imshow("lena", iMat);
16.如何使图像显示窗口能够调节大小
void namedWindow(const string& winname, int flags=WINDOW_AUTOSIZE )
将参数:flags设置成WINDOW_NORMAL即可。
举例:
namedWindow("original image", WINDOW_NORMAL);
imshow("original image", image);
17.如何反转图像灰度,即求图像的负片
将图像中每点的灰度变成(255-gray),其中gray是当前点的灰度。
void bitwise_not(InputArray src, OutputArray dst, InputArray mask=noArray())
18.利用hough变换检测圆
hough变换检测圆
vector<Vec3f> circles;
HoughCircles(inverse, circles, CV_HOUGH_GRADIENT,
1, //累加器的分辨率(图像的尺寸/2)
6, //两个圆之间的最小距离
100, //Canny高阈值
5, //最小投票数
3, 7); //极小极大半径3 10
可以将检测出的圆绘制在图中
//绘制圆
vector<Vec3f>::const_iterator itc = circles.begin();
while(itc != circles.end())
{
circle(inverse, Point((*itc)[0], (*itc)[1]), //圆心
(*itc)[2], //半径
Scalar(255), //颜色
2); //厚度
++itc;
}