Opencv基本操作和配置小记
来源:互联网 发布:网络上个人信息 编辑:程序博客网 时间:2024/06/15 14:03
申明:仅个人笔记,主要来源自课程学习,后续还会补充
目录:
0. 环境配置
1. 基本操作
2. 矩阵运算
零、配置
环境Visual Studio 2013 Opencv2.4.11
关于配置会有些死板,不够灵活。
- 下载Opencv的Windows安装包,将其解压置D:\opencv2.4.11
- 新建Win32控制台应用程序,建立一个工程
- 项目创建好了,右击项目名,点击“属性”
- 点击C/C++->常规->附加包含目录项下拉列表中的“编辑”,然后添加一个新的包含目录路径:D:\opencv2.4.11\opencv\include
- 点击链接器->常规->附加库目录下拉列表中的”编辑”,然后添加一个新的附加库路径:D:\opencv2.4.11\opencv\x86\v12\lib
- 设置连接器->输入->附加依赖项为
opencv_core2411d.lib
opencv_coreimgproc2411d.lib
opencv_highgui2411d.lib
(注:只填这三个,因为目前只是用到这三个。另外, 这里用到的都是d结尾的库文件,表示的是调试版本的。关于发布版本的库,提一下,发布版本的库文件的速度比调试版本的库的速度要高) - 将D:\opencv2.4.11\opencv\x86\vc12\bin下的文件拷贝置如下目录:
64位系统: “C:\Windows\SysWOW64”
32位系统: “C:\Windows\system32”
一、基本操作
/* 以下的程序是本人在初学阶段自己写的一些代码,一些对基本知识的注释还是相较全面的。 其中不乏一些有意思的代码比如借助投票器的思想,实现对几何图形的中心的检测*/#include <opencv2/core/core.hpp>// 基本的结构,架构和线性代数,DFT,xml和I/O接口函数等#include <opencv2/highgui/highgui.hpp>// 图像和视频接口库#include <opencv2/imgproc/imgproc.hpp>// image process 图像处理函数库(滤波,高斯模糊,形态学膨胀/腐蚀)using namespace cv;#include <iostream>using namespace std;/*直方图部分*/void CalcHist(const Mat * image, Mat & hist, int histSize);/*require:hist 为直方图数据name 为绘制窗口名称histSize 表示直方图的列数*/void DrawHist(Mat & hist, string name = "Hist", int histSize = 256);/* 根据提供的阈值对图像进行分割*/Mat cut(const Mat & image, uchar thresold, bool flag);void findCenterOfCircle(const Mat & image);int calcAverageRadius(Mat image, int centerX, int centerY);/* 累计直方图 */Mat cumulativeHist(Mat & hist);/* 根据提供的累积直方图生成查找表*/Mat LUT(Mat & cumuHist, int start = 0, int end = 256);void histEqualization(const Mat & image, const Mat & LUT);/*返回一个新的直方图数据*//*正常的直方图均衡化有不足之处:用老师的话讲就是,做直方图均衡化后信息熵降低,而我们总是希望提高信息熵换句话讲,就是,虽然均衡化图像对比度增强,其本质是扩大了量化间隔,而量化级别反而减少了。因而,原来灰度不同的像素,经过处理后,可能变得相同,形成了一片的相同灰度区域,各区域之间有明显的边界,从而出现伪轮廓下面进行直方图规范化意思就是首先给出一个累积直方图,要求将一张图像处理为累积直方图和给定累积直方图一致的结果图像这里指定了一种累积直方图的方法,详情参看代码*/void hitogramEqualizeSpecification(const Mat * src, Mat & dst);/*对比度和亮度调整*/void ContrastBrightnessAdjust(const Mat * src, Mat & dst, float factor, float bias);void ContrastBrightnessAdjust(const unsigned char src_data[], unsigned char dst_dat[], int dataSize, float factor, float bias);/*自动对比度调整算法就是讲整体的范围拉宽为 0~255*/void AutoContrastBrightnessAdjust_GrayImg(const unsigned char src_data[], unsigned char dst_data[], int dataSize);/* 导数滤波*/void diffFilter(const Mat * src, Mat & dst);/* 最小值滤波 requires: size 必须为奇数 */Mat ImageMinimum(const Mat & src, int size);/* 最大值滤波 */Mat ImageMaximum(const Mat & src, int size);/*两张图像相减 */Mat ImageSub(const Mat & a, const Mat & b);/* 最大类间方差法,自动阈值获取*/uchar OTSU(const Mat & src);/* 提高或者降低图像的亮度 传入一张图 彩图或者灰度图都是可以的 bias 偏差,正数负数都是可以的, bias>0 则为提高图像的亮度 bias<0 则降低图像的亮度*/Mat BrightenImage(const Mat & src, int bias = 0);/* 去饱和 src 为RGB彩图 sCol 为颜色饱和度因子 范围 0~1 就是在RGB三维坐标点到其对应的灰度值点的线段上,使得新的RGB坐标点在该线段上发生移动,移动的距离由sCol提供的比例决定*/Mat Destaturate(const Mat& src, double sCol = 1);/* 颜色空间转换*/Mat HSV(const Mat & src);/*Gamma 校正其实也没啥,就是建立一个X,Y的映射表,X,Y画在直角坐标系中也就是一条曲线、Gamma校正主要是涉及到拍照时候入射光与输出信号之间存在着一种映射关系,这种关系不是线性关系,我们反向将之校正,恢复原值所以,建立好一个查找表就OK了*//*两张图像Alpha混合效果*/void on_trackbar(int, void *);const int alpha_slider_max = 100;int alpha_slider;double alpha;double beta;Mat src1;Mat src2;Mat dst;#if 0int main(int argc, char * argv[]){#if 0 Mat img = imread("images/circle.jpg", CV_LOAD_IMAGE_COLOR); findCenterOfCircle(img);#endif#if 0 // 读图,保存图 Mat img = imread("images/airplane.jpg", CV_LOAD_IMAGE_COLOR); namedWindow("img"); // 这句话是规范的要写的,不写好像也是OK的 resizeWindow("img", 200, 200); resize(img, img, Size(), 0.3, 0.3);// 缩小图像 imshow("img", img); imwrite("imwrite.jpg", img); waitKey(0); // 进入事件循环#endif #if 0 // 灰度图绘制直方图和装箱直方图 Mat img = imread("images/pout.bmp", CV_LOAD_IMAGE_GRAYSCALE); imshow("img", img); Mat hist; int histSize = 16; CalcHist(&img, hist, histSize); DrawHist(hist, "hist", 256); waitKey(0);#endif #if 0 // 绘制累积直方图 Mat img = imread("images/rice.bmp", CV_LOAD_IMAGE_GRAYSCALE); imshow("img", img); Mat hist; int histSize = 256; CalcHist(&img, hist, histSize); cout << "hist rows: " << hist.rows << endl; DrawHist(hist, "hist"); DrawHist(cumulativeHist(hist), "cumulativeHist"); waitKey(0);#endif#if 0 /* 彩图的直方图及其装箱图*/ Mat src = imread("images/fruit.png"); vector<Mat> mv; imshow("src", src); split(src, mv); imshow("R ", mv[0]); imshow("G ", mv[1]); imshow("B ", mv[2]); Mat hist; int histSize = 256; CalcHist(&mv[0], hist, histSize); DrawHist(hist, "R", 256); CalcHist(&mv[1], hist, histSize); DrawHist(hist, "G", 256); CalcHist(&mv[2], hist, histSize); DrawHist(hist, "B", 256); waitKey(0);#endif#if 0 Mat image = imread(argv[1], CV_LOAD_IMAGE_COLOR); // 图像按比例放大,缩小 // 双线性插值 Mat newImage; resize(image, newImage, Size(), 0.5, 0.5); // 默认使用双线性插值 Mat cubicImage; //imshow("new", newImage); vector<Mat> rgb_planes; split(newImage, rgb_planes); imshow("r", rgb_planes[0]); //imshow("g", rgb_planes[1]); //imshow("b", rgb_planes[2]); MatND histogram; int histSize = 256; float range[] = { 0, 255 }; const float * ranges[] = { range }; const int channels = 0; calcHist(&rgb_planes[2], 1, &channels, Mat(), histogram, 1, &histSize, ranges, true, false); float * h = (float*)histogram.data; double hh[256]; if (h) { for (int i = 0; i < histogram.rows; i++) { hh[i] = h[i]; cout << hh[i] << " "; if ((i + 1) % 8 == 0) cout << endl; } } cout << "rows : " << histogram.rows << endl; cout << "cols : " << histogram.cols << endl; cout << "step : " << histogram.step << endl; waitKey(0);#endif#if 0 // 增强对比度 Mat src, dst; src = imread("images/barbara.png", CV_LOAD_IMAGE_GRAYSCALE); // 以灰度图方式载图一张图片 imshow("jack", src); ContrastBrightnessAdjust(&src, dst, 3, 0); imshow("contrast", dst); waitKey(0);#endif#if 0 // 增强对比度 Mat src, dst; src = imread("images/cock256rgb.jpg", CV_LOAD_IMAGE_GRAYSCALE); // 以灰度图方式载图一张图片 imshow("jack", src); src.copyTo(dst); ContrastBrightnessAdjust(src.data, dst.data, src.rows*src.cols, 2, 0); imshow("res", dst); waitKey(0);#endif#if 0 /* 自动亮度对比度调整 */ Mat src, dst; src = imread("images/ladyrgb.png", CV_LOAD_IMAGE_GRAYSCALE); // 以灰度图方式载图一张图片 imshow("jack", src); src.copyTo(dst); AutoContrastBrightnessAdjust_GrayImg(src.data, dst.data, src.rows*src.cols); imshow("res", dst); waitKey(0);#endif#if 0 // 直方图均衡化 Mat src, dst; src = imread("images/ladyrgb.png", CV_LOAD_IMAGE_GRAYSCALE); // 以灰度图方式载图一张图片 Mat hist; int histSize = 256; CalcHist(&src, hist, histSize); Mat cumuHist = cumulativeHist(hist); DrawHist(cumulativeHist(hist)); histEqualization(src, LUT(cumuHist)); waitKey(0);#endif#if 0 src1 = imread("alpha.png", CV_LOAD_IMAGE_GRAYSCALE); src2 = imread("beta.png", CV_LOAD_IMAGE_GRAYSCALE); alpha_slider = 0; char TrackbarName[50]; sprintf(TrackbarName, "Alpha x %d", alpha_slider_max); createTrackbar(TrackbarName, "Linear Blend", &alpha_slider, alpha_slider_max, on_trackbar); on_trackbar(alpha_slider, 0); waitKey(0);#endif#if 0 Mat src, dst; src = imread("images/ladyrgb.png", CV_LOAD_IMAGE_GRAYSCALE); // 以灰度图方式载图一张图片 imshow("jack", src); hitogramEqualizeSpecification(&src, dst); imshow("res", dst); Mat hist; CalcHist(&src, hist, 256); DrawHist(cumulativeHist(hist), "src"); CalcHist(&dst, hist, 256); DrawHist(cumulativeHist(hist), "dst"); waitKey(0);#endif#if 0 // 滤波器 Mat src = imread("noiseCircle.png", CV_LOAD_IMAGE_GRAYSCALE); Mat dst = Mat::zeros(src.size(), src.type()); // 根据原图像构建一个大小和类型相同的图像矩阵 imshow("src", src); /* putText : opencv 接口 功能在图像的指定位置写指定颜色文本 */ putText(dst, "Write Some Text", Point(src.cols / 4, src.rows / 2), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255)); imshow("Median Blur", dst); //waitKey(0); int MAX_KERNEL_LENGTH = 31; for (int i = 1; i < MAX_KERNEL_LENGTH; i += 2) { // Size(i,i) 表示滤波核的大小 blur(src, dst, Size(i, i), Point(-1, -1));// 箱式滤波 imshow("box blur", dst); GaussianBlur(src, dst, Size(i, i), 0, 0);// 高斯滤波 其中Size(i,i) 必须是奇数 cout << "GaussianBlur" << endl; imshow("GaussianBlur", dst); medianBlur(src, dst, i);// 中值滤波 //medianBlur(dst, dst, i);// 中值滤波 二次 imshow("MedianBlur", dst); int delay = 100; waitKey(delay); cout << "GaussianBlur end" << endl; } waitKey(0);#endif#if 0 // 创建浮点矩阵 /* CvMat* cvCreateMat(int rows, int cols, int type); type: 矩阵元素类型.格式为CV_(S | U | F)C.例如 : CV_8UC1 表示8位无符号单通道矩阵, CV_32SC2表示32位有符号双通道矩阵. */ Mat diff = cvCreateMat(100, 100,CV_32F); Mat img = imread("images/shadow.png", CV_LOAD_IMAGE_COLOR); imshow("img", img); cout << img.cols << " " << img.step << endl; Mat dst; diffFilter(&img, dst); waitKey(0);#endif#if 0 /* 大米图分割 (其中使用了自动阈值分割法确定阈值)*/ Mat src = imread("images/rice.bmp", CV_LOAD_IMAGE_GRAYSCALE); imshow("src", src); Mat res = ImageMinimum(src, 7);// 这里的滤波和的尺寸的选取和大米的尺寸有关, imshow("MinRes", res); Mat subRes = ImageSub(src, res); Mat hist; int histSize = 256; CalcHist(&subRes, hist, histSize); DrawHist(hist, "hist", 256); uchar threshold = OTSU(subRes); cout << (int)threshold << endl; //threshold = 30; Mat cutRes1 = cut(subRes, threshold,false); imshow("cutRes1", cutRes1); /* 下面借助一次开运算进行去噪声 */ Mat a = ImageMinimum(cutRes1, 3);// 腐蚀 imshow("blur", a); Mat b = ImageMaximum(a, 3);// 膨胀 imshow("dilate", b); imshow("b", b); waitKey(0);#endif#if 1 /* 提高或者降低图像的亮度 */ Mat src = imread("images/ladyind.png", CV_LOAD_IMAGE_COLOR); imshow("src",src); Mat dst = BrightenImage(src, 80); imshow("dst",dst); waitKey(0);#endif#if 0 // 彩图去饱和 (代码思想就是让三维空间的RGB坐标往灰度点上靠近) Mat src = imread("images/ladyind.png"); Mat dst = Destaturate(src,0.3); imshow("src", src); imshow("Destaturate", dst); waitKey(0);#endif return 0;}#endif#if 0#include"opencv/cv.h"#include"opencv2/highgui/highgui.hpp"#include"opencv2/imgproc/imgproc.hpp"using namespace cv;const int slider_h_max = 360;const int slider_h_center = 180;int slider_h;const int slider_s_max = 510;const int slider_s_center = 255;int slider_s;const int slider_v_max = 510;const int slider_v_center = 255;int slider_v;Mat src;Mat hsv;Mat hsv_current;//Mat dst;void on_trackbar_h(int, void*){ unsigned char *p, *q; if (hsv_current.isContinuous() && hsv.isContinuous()) { for (p = hsv_current.data, q = hsv.data; p < hsv_current.dataend; p += 3, q += 3) { *p = MAX(0, MIN(255, (*q) + slider_h - slider_h_center)); } } cvtColor(hsv_current, dst, CV_HSV2BGR); imshow("H_adjust", dst); imshow("S_adjust", dst); imshow("V_adjust", dst);}void on_trackbar_s(int, void*){ unsigned char *p, *q; if (hsv_current.isContinuous() && hsv.isContinuous()) { for (p = hsv_current.data, q = hsv.data; p < hsv_current.dataend; p += 3, q += 3) { *(p+1) = MAX(0, MIN(255, (*(q+1)) + slider_s - slider_s_center)); } } cvtColor(hsv_current, dst, CV_HSV2BGR); imshow("H_adjust", dst); imshow("S_adjust", dst); imshow("V_adjust", dst);}void on_trackbar_v(int, void*){ unsigned char *p, *q; if (hsv_current.isContinuous() && hsv.isContinuous()) { for (p = hsv_current.data, q = hsv.data; p < hsv_current.dataend; p += 3, q += 3) { *(p+2) = MAX(0, MIN(255, (*(q+2)) + slider_v - slider_v_center)); } } cvtColor(hsv_current, dst, CV_HSV2BGR); imshow("H_adjust", dst); imshow("S_adjust", dst); imshow("V_adjust", dst);}int main(int argc, char** argv){ src = imread("C:\\Users\\Administrator\\Desktop\\图像\\图像\\baboon.jpg", 1); if (!src.data) { printf("error loading src \n"); return -1; } cvtColor(src, hsv, CV_BGR2HSV); hsv.copyTo(hsv_current); slider_h = slider_h_center; slider_s = slider_s_center; slider_v = slider_v_center; namedWindow("H_adjust", 1); namedWindow("S_adjust", 1); namedWindow("V_adjust", 1); char TrackbarName[50]; sprintf(TrackbarName, "h %d", slider_h_max); createTrackbar(TrackbarName, "H_adjust", &slider_h, slider_h_max, on_trackbar_h); on_trackbar_h(slider_h, 0); sprintf(TrackbarName, "s %d", slider_s_max); createTrackbar(TrackbarName, "S_adjust", &slider_s, slider_s_max, on_trackbar_s); on_trackbar_s(slider_s, 0); sprintf(TrackbarName, "v %d", slider_v_max); createTrackbar(TrackbarName, "V_adjust", &slider_v, slider_v_max, on_trackbar_v); on_trackbar_v(slider_v, 0); waitKey(0); return 0;}#endif#if 0#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <iostream>#include <opencv/cv.h>#include <opencv/highgui.h>using namespace cv;using namespace std;int main(int argc, char** argv){ Mat image; image = imread(argv[1], CV_LOAD_IMAGE_COLOR); int cols, rows, i, j; cols = image.cols; rows = image.rows; cout << "channels : " << image.channels() << endl; cout << "cols = " << cols << " rows = " << rows << endl; cout << "step: " << image.step << endl; // 步长 imshow("JACK", image); Vec3b green(0, 255, 0); green[0] = 10; green[1] = 55; Mat gray;// 彩图转灰度图 cvtColor(image, gray, CV_RGB2GRAY, 0); for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { uchar t = image.at<Vec3b>(i, j)[0]; image.at<Vec3b>(i, j)[0] = image.at<Vec3b>(i, j)[1]; image.at<Vec3b>(i, j)[1] = image.at<Vec3b>(i, j)[2]; image.at<Vec3b>(i, j)[2] = t; } } imshow("rgb revert", image); imshow("gray", gray); for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { image.at<Vec3b>(i, j) = green; } } imshow("res", image); IplImage * img = cvLoadImage(argv[1], 1); Mat old(img); imshow("old", old); int hist[256] = { 0 }; for (int i = 0; i < gray.rows - 200; i++) { for (int j = 0; j < gray.cols - 200; j++) { //cout << (int)gray.at<uchar>(i, j) << " "; hist[gray.at<uchar>(i, j)] ++; } //cout << endl; } for (int i = 0; i < 256; i++) { if ((i + 1) % 16 == 0) cout << endl; cout << hist[i] << " "; } cout << "gray step = " << gray.step << endl; cout << "image step = " << image.step << endl; /*if (gray.isContinuous()) { for (int i = 0; i < gray.rows; i++) { for (int j = 0; j < gray.cols; j++) { uchar temp = (*p)[0] } } }*/ //Vec3b color(30, 40, 100); //for (int i = 0; i < image.rows; i++) { // for (int j = 0; j < image.cols; j++) { // image.at<Vec3b>(i, j) = color; // } //} //imshow("color", image); for (int i = 0; i < gray.rows; i++) {// 灰度图的补图 for (int j = 0; j < gray.cols; j++) { gray.at<uchar>(i, j) = 255 - gray.at<uchar>(i, j); } } imshow("revert color", gray); CvHistogram waitKey(0); return 0;}#endifvoid CalcHist(const Mat * image, Mat & hist, int histSize){ /*float range[] = { 0, 256 }; const float * histRange = { range }; bool uniform = true; bool accumulate = false; calcHist(image, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);*/ hist = Mat::zeros(histSize, 1, CV_32F); float * p = (float*)hist.data; for (int i = 0; i < image->rows; i++) { for (int j = 0; j < image->cols; j++) { p[image->at<uchar>(i, j)] ++; } } return;}void DrawHist(Mat & hist, string name, int histSize){ int w = 512; int h = 120; Mat histImage(h, w, CV_8UC1, Scalar(0, 0, 0)); uchar * p = histImage.data; cout << "histImage step : " << histImage.step << endl; int binHeight = 0; float * q = (float*)hist.data; float max = q[0];// 找到最大值,然后对其进行归一化 for (int i = 1; i < hist.rows; i++) { if (q[i] > max) max = q[i]; } q = (float*)hist.data; for (int i = 0; i < w; i++) { binHeight = (int)(h*q[i*hist.rows / w] / max); for (int k = h - binHeight; k < h; k++) { p[k*histImage.step + i] = 255; } } imshow(name, histImage);}Mat cut(const Mat & image, uchar thresold, bool flag){ unsigned char * p = image.data; Mat newImage; image.copyTo(newImage); for (int i = 0; i < newImage.rows; i++) { p = newImage.data + newImage.step * i; for (int j = 0; j < newImage.cols; j++) { if (flag) { if (p[j] < thresold) p[j] = 0; } else { if (p[j] > thresold) p[j] = 255; } } } return newImage;}void findCenterOfCircle(const Mat & image){ int * vote = new int[image.step]; for (int i = 0; i < image.step; i++) vote[i] = 0; unsigned char * p = image.data; int x1 = 0, x2 = 0; bool flag = true; for (int i = 0; i < image.rows; i++) { flag = true; p = image.data + image.step * i; for (int j = 0; j < image.step; j++) { if (p[j] < 128) { if (flag) { x1 = j; x2 = j; flag = false; } x2 = j; } } if (!flag) vote[(x1 + x2) / 2] ++; } /*for (int i = 0; i < image.step; i++) { cout << vote[i] << " "; if ((i + 1) % 20 == 0) cout << endl; }*/ int max = 0; for (int i = 1; i < image.step; i++) { if (vote[i] > vote[max]) { max = i; } } cout << "X : " << max << endl; int centerX = max; Mat newImage; image.copyTo(newImage); imshow("newImage", newImage); for (int i = 0; i < newImage.rows; i++) { p = newImage.data + i*newImage.step; p[max] = 0; } //imshow("newImage", newImage); // 投票器清空 for (int i = 0; i < image.step; i++) { vote[i] = 0; } int y1 = 0, y2 = 0; // 列扫描 for (int i = 0; i < image.step; i++) { flag = true; for (int j = 0; j < image.rows; j++) { p = image.data + j*image.step + i; if (*p < 128) { if (flag) { y1 = j; flag = false; } y2 = j; } } if (!flag) { vote[(y1 + y2) / 2] ++; } } /*for (int i = 0; i < image.step; i++) { cout << vote[i] << " "; if ((i + 1) % 20 == 0) cout << endl; }*/ max = 0; for (int i = 1; i < image.step; i++) { if (vote[i] > vote[max]) { max = i; } } cout << "Y : " << max << endl; int centerY = max; p = newImage.data + max * newImage.step; for (int i = 0; i < newImage.step; i++) { *(p++) = 0; } imshow("newImage", newImage); cout << "radius : " << calcAverageRadius(image, centerX, centerY); int radius = calcAverageRadius(image, centerX, centerY); Point center = Point(centerX, centerY); circle(newImage, center, radius, Scalar(0, 0, 0)); imshow("image", newImage);; delete[]vote;}int calcAverageRadius(Mat image, int centerX, int centerY){ unsigned char * p = image.data; long sum = 0; int k = 0; for (int i = 0; i < image.rows; i++) { p = image.data + i * image.step; for (int j = 0; j < image.step; j++) { if (p[j] < 128) { sum += (int)sqrt(((j - centerX)*(j - centerX) + (i - centerY)*(i - centerY))); k++; } } } if (k != 0) { return sum / k; } return 0;}Mat cumulativeHist(Mat & hist){ cout << "hist rows: " << hist.rows << endl; cout << "hist cols: " << hist.cols << endl; Mat cumuHist; hist.copyTo(cumuHist); float * p = (float*)cumuHist.data; // 注意数据类型 for (int i = 1; i < hist.rows; i++) p[i] += p[i - 1]; for (int i = 0; i < hist.rows; i++) { cout << p[i] << " "; if ((i + 1) % 8 == 0) cout << endl; } return cumuHist;}Mat LUT(Mat & cumuHist, int start, int end){ float sum = 0; float * p = (float*)cumuHist.data; sum = p[255]; Mat temp; cumuHist.copyTo(temp); p = (float*)temp.data; for (int i = 0; i < temp.rows; i++) { p[i] /= sum; cout << p[i] << " "; if ((i + 1) % 8 == 0) cout << endl; } Mat LUT(end - start, 1, CV_8U); cout << "sum : " << sum << endl; unsigned char * q = (unsigned char*)LUT.data; p = (float*)temp.data; for (int i = 0; i < end - start; i++) { q[i] = (unsigned char)(start + p[i] * (end - start - 1)); cout << (int)q[i] << " "; if ((i + 1) % 8 == 0) cout << endl; } return LUT;}void histEqualization(const Mat & image, const Mat & LUT){ unsigned char * p = NULL; unsigned char * q = LUT.data; Mat newImage; image.copyTo(newImage); for (int i = 0; i < newImage.rows; i++) { p = newImage.data + newImage.cols * i; for (int j = 0; j < newImage.cols; j++) { p[j] = q[p[j]]; } } imshow("origin image", image); imshow("hist equalization", newImage); Mat hist; int histSize = 256; CalcHist(&image, hist, histSize); DrawHist(hist, "Old"); DrawHist(cumulativeHist(hist), "Old Cumulative Hist"); CalcHist(&newImage, hist, histSize); DrawHist(hist, "New"); DrawHist(cumulativeHist(hist), "New Cumulative Hist");}void hitogramEqualizeSpecification(const Mat * src, Mat & dst){ float hist[256] = { 0 }; unsigned char * p = NULL; for (int i = 0; i < src->rows; i++) { p = src->data + i*src->step; for (int j = 0; j < src->cols; j++) { hist[p[j]] ++; } } unsigned char table[256]; float s = 0; for (int i = 0; i < 256; i++) s += sqrt(hist[i]); float sum = 0; for (int i = 0; i < 256; i++) { sum += sqrt(hist[i]); table[i] = cvFloor(sum * 255 / s); } for (int i = 0; i < 256; i++) cout << (int)table[i] << " "; src->copyTo(dst); for (int i = 0; i < src->rows; i++) { p = dst.data + i*dst.step; for (int j = 0; j < src->cols; j++) { p[j] = table[p[j]]; } } return;}void ContrastBrightnessAdjust(const Mat * src, Mat & dst, float factor, float bias){ src->copyTo(dst); unsigned char * p = dst.data; for (int i = 0; i < src->rows; i++) { p = dst.data + i*dst.step; for (int j = 0; j < src->cols; j++) { float tmp = (p[j] - 128)*factor + bias + 128; if (tmp > 255) p[j] = 255; else if (tmp < 0) p[j] = 0; else p[j] = (unsigned char)tmp; } } return;}void ContrastBrightnessAdjust(const unsigned char src_data[], unsigned char dst_data[], int dataSize, float factor, float bias){ const unsigned char * p = src_data; unsigned char * q = dst_data; for (int i = 0; i < dataSize; i++) { *q++ = cvRound(MAX(0, MIN((*p - 128)*factor + 128 + bias, 255)));// 这里MAX, MIN用的很好,很好的替代了对255和0的判断 p++; } return;}void AutoContrastBrightnessAdjust_GrayImg(const unsigned char src_data[], unsigned char dst_data[], int dataSize){ const unsigned char * p = src_data; unsigned char * q = dst_data; unsigned char min = 255, max = 0; // 找到图片中的最大值和最小值 for (int i = 0; i < dataSize; i++) { if (src_data[i] < min) min = src_data[i]; if (src_data[i] > max) max = src_data[i]; } for (int i = 0; i < dataSize; i++) { *q++ = cvRound(MAX(0, MIN((*p - min)*(255.0 / (max - min)), 255)));// 不能大于255, 不能小于0 p++; } return;}void on_trackbar(int, void *){ //alpha = (double)alpha_slider / alpha_slider_max; alpha = 0.6; beta = (1.0 - alpha); src1.copyTo(dst); if (src1.isContinuous() && src2.isContinuous() && dst.isContinuous()) { unsigned char * s1, *s2, *d; for (s1 = src1.data, s2 = src2.data, d = dst.data; d < dst.dataend; s1++, s2++, d++) *d = (unsigned char)((*s1)*alpha + (*s2)*beta); } imshow("alpha", src1); imshow("beta", src2); imshow("Liner Blend", dst);// 线性混合,确实是线性混合 就是将两张图片按照不同的比例兑好}void diffFilter(const Mat * src, Mat & dst){ Mat diff = cvCreateMat(src->rows, src->cols, CV_32F); memset(diff.data, 0, diff.rows*diff.step); src->copyTo(dst); // 横向差分滤波 unsigned char * p = src->data; float * q = (float*)diff.data; cout << diff.step << " "<< src->step; /*for (int i = 0; i < src->rows; i++) { for (int j = 1; j < src->cols-1; j++) { } }*/ // 纵向差分滤波}/* 最小值滤波 */Mat ImageMinimum(const Mat & src, int size){ Mat res; src.copyTo(res); int i, j, m, n; cout << src.rows << ", " << src.cols << endl; for (i = size/2; i < src.rows-size/2-1; i++) { for (j = size/2; j < src.cols-size/2-1; j++) { //cout << "j = " << j << endl; int min = src.at<uchar>(i, j); for (m = i - size / 2; m <= i + size / 2; m++) for (n = j - size / 2; n <= j + size / 2; n++) if (min > src.at<uchar>(m, n)) min = src.at<uchar>(m, n); res.at<uchar>(i, j) = min; } //cout << "i = " << i << endl; } //imshow("Min", res); return res;}/* 最大值滤波 */Mat ImageMaximum(const Mat & src, int size){ Mat res; src.copyTo(res); int i, j, m, n; cout << src.rows << ", " << src.cols << endl; for (i = size / 2; i < src.rows - size / 2 - 1; i++) { for (j = size / 2; j < src.cols - size / 2 - 1; j++) { int max = src.at<uchar>(i, j); for (m = i - size / 2; m <= i + size / 2; m++) for (n = j - size / 2; n <= j + size / 2; n++) if (max < src.at<uchar>(m, n)) max = src.at<uchar>(m, n); res.at<uchar>(i, j) = max; } } //imshow("Max", res); return res;}Mat ImageSub(const Mat & a, const Mat & b){ Mat res; a.copyTo(res); for (int i = 0; i < a.rows; i++) { for (int j = 0; j < a.cols; j++) { res.at<uchar>(i, j) = a.at<uchar>(i, j) - b.at<uchar>(i, j); } } imshow("subRes", res); return res;}uchar OTSU(const Mat & src){ Mat hist; int histSize = 256; CalcHist(&src, hist, histSize); float * p = (float*)hist.data; float variance[255] = { 0 };// 记录所有类间方差 float x0 = 0, x1; float a0 = 0, a1 = 0,a = 0; float sum0 = 0, sum1 = 0; float sum = 0; for (int i = 0; i < 256; i++) sum += p[i]*i; int cnt = src.rows * src.cols; // 总体平均灰度 a = sum/cnt; //cout << "总体平均灰度: " << a << endl; p = (float*)hist.data; for (int i = 1; i < 256; i++) { // 统计人数 x0 += p[i-1]; x1 = cnt - x0; sum0 += (i - 1)*p[i - 1]; sum1 = sum - sum0; //cout << "sum0 = " << sum0 << " , " << sum1 << endl; // 计算平均灰度 a0 = sum0 / x0; a1 = sum1 / x1; if (sum0 == 0) a0 = 0; if (sum1 == 0) a1 = 0; variance[i - 1] = (x0 / cnt)*(a0 - a)*(a0 - a) + (x1 / cnt)*(a1 - a)*(a1 - a); } /*p = (float*)hist.data; for (int i = 0; i < 256; i++) { cout << (int)p[i] << " "; if ((i + 8) % 8 == 0) cout << endl; }*/ /*for (int i = 0; i < 255; i++) { cout << variance[i] << " "; if ((i + 8) % 8 == 0) cout << endl; }*/ int max = 0; for (int i = 1; i < 255; i++) { if (variance[max] < variance[i]) max = i; } return max;}Mat BrightenImage(const Mat & src, int bias){ Mat dst; int t; src.copyTo(dst); unsigned char table[256]; for (int i = 0; i < 256; i++) table[i] = MAX(0, MIN(255, i + bias)); for (int i = 0; i < src.rows; i++) { for (int j = 0; j < src.step; j++) { dst.at<uchar>(i, j) = table[src.at<uchar>(i, j)]; } } return dst;}Mat Destaturate(const Mat & src, double sCol){ Mat dst; src.copyTo(dst); float deltaX; float deltaY; float deltaZ; float grayValue; Vec3b * p = (Vec3b*)(dst.data); if (dst.isContinuous()) { for (int i = 0; i < dst.rows; i++) { for (int j = 0; j < dst.cols; j++) { grayValue = 0.299*(*p)[0] + 0.587*(*p)[1] + 0.114*(*p)[2]; deltaX = (*p)[0] - grayValue; deltaY = (*p)[1] - grayValue; deltaZ = (*p)[2] - grayValue; (*p)[0] = grayValue + sCol * deltaX; (*p)[1] = grayValue + sCol * deltaY; (*p)[2] = grayValue + sCol * deltaZ; p++; } } } return dst;}Mat HSV(const Mat & src){ Mat dst; //Vec3b * p = (Vec3b *)src.data; //for (int i = 0; i < src.rows; i++) { // for (int j = 0; j < src.cols; j++) { // // } //} //TODO return dst;}
By Jack Lu 2017年5月22日 22:57:56
二、矩阵运算
Mat A = Mat::ones(2, 3, CV_32FC1); Mat B = Mat::ones(3, 2, CV_32FC1); Mat AB; A.at<float>(0, 0) = 2; A.at<float>(0, 1) = 2; A.at<float>(0, 2) = 2; A.at<float>(1, 0) = 4; A.at<float>(1, 1) = 5; A.at<float>(1, 2) = 6; B.at<float>(0, 0) = 1; B.at<float>(0, 1) = 2; B.at<float>(1, 0) = 2; B.at<float>(1, 1) = 4; B.at<float>(2, 0) = 5; B.at<float>(2, 1) = 6; AB = A*B; cout << "A=\n" << A << endl << endl; cout << "B=\n" << B << endl << endl; cout << "AB=\n" << AB << endl << endl;
我之前不知道Opencv支持矩阵运算
除了上面的矩阵相乘运算,还有向量的点运算,矩阵对应点乘积运算。
详细请看这篇文章http://blog.csdn.net/dcrmg/article/details/52404580
By Jack Lu 2017年6月23日 07:48:09
阅读全文
0 0
- Opencv基本操作和配置小记
- Emacs基本操作小记
- Ubuntu上配置OpenCV小记
- Qt-Matlab-Opencv配置小记
- openldap基本配置和操作
- PLSQL配置和基本操作
- OpenCV基本操作
- opencv基本操作
- opencv基本图像操作
- opencv基本操作
- OpenCV基本操作
- opencv Mat基本操作
- Opencv基本操作
- OpenCV基本操作学习
- opencv图像基本操作
- OpenCV | 基本操作API
- opencv基本操作(二)
- opencv基本操作(三)
- 门面模式(Facade Pattern)
- [PHP学习] Windows下PHP集成环境配置
- android fastjson的简单使用
- C语言之rand()和srand()函数
- 高效版本控制工具--Git使用教程
- Opencv基本操作和配置小记
- 3164 质因数分解
- 自定义密码 输入界面
- 算法笔记 3.1 简单模拟
- 欢迎使用CSDN-markdown编辑器
- Spring源码分析之lazy-init属性的配置
- 求1+2+3+...+n(java版)
- sql server 安装到服务器上时出现的错误,以及怎么去解决之后有可能出现的一系列错误。
- JavaWeb中乱码问题