整理自己工程中常用的一些opencv 函数,一般是opencv不自带的。
1:求距离
int get_distance(cv::Point p1,cv::Point p2);
int get_distance(cv::Point p1,cv::Point p2)
{
int x_2 = (p1.x-p2.x)*(p1.x-p2.x);
int y_2 = (p1.y-p2.y)*(p1.y-p2.y);
return sqrt(x_2+y_2);
}
2:导向滤波器
cv::Mat guidedFilter(cv::Mat &srcMat, cv::Mat &guidedMat, int radius, double eps);
cv::Mat guidedFilter(cv::Mat &srcMat, cv::Mat &guidedMat, int radius, double eps)
{
//------------【0】转换源图像信息,将输入扩展为64位浮点型,以便以后做乘法------------
srcMat.convertTo(srcMat, CV_64FC1);
guidedMat.convertTo(guidedMat, CV_64FC1);
//--------------【1】各种均值计算----------------------------------
cv::Mat mean_p, mean_I, mean_Ip, mean_II;
boxFilter(srcMat, mean_p, CV_64FC1, cv::Size(radius, radius));//生成待滤波图像均值mean_p
boxFilter(guidedMat, mean_I, CV_64FC1, cv::Size(radius, radius));//生成引导图像均值mean_I
boxFilter(srcMat.mul(guidedMat), mean_Ip, CV_64FC1, cv::Size(radius, radius));//生成互相关均值mean_Ip
boxFilter(guidedMat.mul(guidedMat), mean_II, CV_64FC1, cv::Size(radius, radius));//生成引导图像自相关均值mean_II
//--------------【2】计算相关系数,计算Ip的协方差cov和I的方差var------------------
cv::Mat cov_Ip = mean_Ip - mean_I.mul(mean_p);
cv::Mat var_I = mean_II - mean_I.mul(mean_I);
//---------------【3】计算参数系数a、b-------------------
cv::Mat a = cov_Ip / (var_I + eps);
cv::Mat b = mean_p - a.mul(mean_I);
//--------------【4】计算系数a、b的均值-----------------
cv::Mat mean_a, mean_b;
cv::boxFilter(a, mean_a, CV_64FC1, cv::Size(radius, radius));
cv::boxFilter(b, mean_b, CV_64FC1, cv::Size(radius, radius));
//---------------【5】生成输出矩阵------------------
cv::Mat dstImage = mean_a.mul(srcMat) + mean_b;
return dstImage;
}
3: grb高通
cv::Mat rgb_HighPass(cv::Mat src,int R)
cv::Mat rgb_HighPass(cv::Mat src,int R)
{
int width = src.cols;
int heigh = src.rows;
cv::Mat img;
src.copyTo(img);
cv::Mat avg;
cv::blur(img, avg, cv::Size(R, R));
cv::Mat dst(img.size(), CV_8UC3);
float tmp;
for (int y = 0; y<heigh; y++)
{
uchar* imgP = img.ptr<uchar>(y);
uchar* avgP = avg.ptr<uchar>(y);
uchar* dstP = dst.ptr<uchar>(y);
for (int x = 0; x<width; x++)
{
float r0 = ((float)imgP[3 * x] - (float)avgP[3 * x]);
tmp = 128 + abs(r0)*r0 / (2 * R);
tmp = tmp>255 ? 255 : tmp;
tmp = tmp<0 ? 0 : tmp;
dstP[3 * x] = (uchar)(tmp);
float r1 = ((float)imgP[3 * x + 1] - (float)avgP[3 * x + 1]);
tmp = 128 + abs(r1)*r1 / (2 * R);
tmp = tmp>255 ? 255 : tmp;
tmp = tmp<0 ? 0 : tmp;
dstP[3 * x + 1] = (uchar)(tmp);
float r2 = ((float)imgP[3 * x + 2] - (float)avgP[3 * x + 2]);
tmp = 128 + abs(r2)*r2 / (2 * R);
tmp = tmp>255 ? 255 : tmp;
tmp = tmp<0 ? 0 : tmp;
dstP[3 * x + 2] = (uchar)(tmp);
}
}
return dst;
}
4: 灰度高通
cv::Mat gray_HighPass(cv::Mat src,int R= 11);
int width = src.cols;
int heigh = src.rows;
cv::Mat img;
src.copyTo(img);
cv::Mat avg;
cv::blur(img, avg, cv::Size(R, R));
cv::Mat dst(heigh,width, CV_8UC1);
float tmp;
for (int y = 0; y < heigh; y++)
{
uchar* imgP = img.ptr<uchar>(y);
uchar* avgP = avg.ptr<uchar>(y);
uchar* dstP = dst.ptr<uchar>(y);
for (int x = 0; x < width; x++)
{
float r0 = ((float)imgP[x] - (float)avgP[x]);
tmp = 128 + abs(r0)*r0 / (2 * R);
tmp = tmp>255 ? 255 : tmp;
tmp = tmp<0 ? 0 : tmp;
dstP[x] = (uchar)(tmp);
}
}
return dst;
5:获取最小外接矩形
cv::Rect get_minroi(vector<cv::Point> input)
cv::Rect get_minroi(vector<cv::Point> input)
{
cv::Rect to_return;
vector<int> x;
vector<int> y;
int max_x = 0;
int min_x = 1000;
int max_y = 0;
int min_y = 1000;
for (int i = 0; i < input.size(); i++)
{
x.push_back(input[i].x);
y.push_back(input[i].y);
}
for (int i = 0; i < x.size(); i++)
{
if (x[i] > max_x)
{
max_x = x[i];
}
if (y[i] > max_y)
{
max_y = y[i];
}
if (x[i] < min_x)
{
min_x = x[i];
}
if (y[i] < min_y)
{
min_y = y[i];
}
}
to_return.x = min_x;
to_return.y = min_y;
to_return.width = abs(max_x - min_x);
to_return.height = abs(max_y - min_y);
return to_return;
}
6:矩阵比较,必须大小相同
double compare_mat(cv::Mat temp, cv::Mat input);
double compare_mat(cv::Mat temp, cv::Mat input)
{
int yes = 0;
int all = 0;
for (int i = 0; i < temp.rows; i++)
{
for (int j = 0; j < temp.cols; j++)
{
all++;
uchar data = temp.at<uchar>(i,j);
uchar in_data = input.at<uchar>(i, j);
if (data == in_data)
{
yes++;
}
}
}
double d_y = double(yes);
double d_a = double(all);
return double(d_y / d_a);
}
7:去除单个轮廓周围的白色
cv::Mat wipe_off_white(cv::Mat input);
cv::Mat wipe_off_white(cv::Mat input)
{
cv::Mat gray;
cv::cvtColor(input, gray, CV_BGR2GRAY);
cv::threshold(gray, gray, 80, 255, cv::THRESH_BINARY);
vector<vector<cv::Point>> contours;
vector<cv::Vec4i> hierarchy;
double max_contours_area = 0.0;
cv::Mat new_gray(gray.rows, gray.cols+10, CV_8UC1);
for (int i = 0; i < new_gray.cols; i++)
{
if (i <gray.cols+5)
{
if (i <5 && i >=0)
{
for (int j = 0; j < gray.rows; j++)
{
new_gray.at<uchar>(j, i) = 255;
}
}
else
{
for (int j = 0; j < gray.rows; j++)
{
uchar data = gray.at<uchar>(j, i-5);
new_gray.at<uchar>(j, i) = data;
}
}
}
else
{
for (int j = 0; j < gray.rows; j++)
{
new_gray.at<uchar>(j, i) = 255;
}
}
}
cv::Mat to_draw(new_gray.size(), CV_8UC3);
cv::cvtColor(new_gray, to_draw, CV_GRAY2BGR);
cv::findContours(new_gray, contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);
for (int i = 0; i < contours.size(); i++)
{
cv::RotatedRect rectPoint = minAreaRect(contours[i]);
cv::Point2f fourPoint2f[4];
rectPoint.points(fourPoint2f);
int width = abs(get_distance(fourPoint2f[1], fourPoint2f[2]));
int height = abs(get_distance(fourPoint2f[1], fourPoint2f[0]));
if (width >= 3 && height >= 3 && width < (new_gray.cols-2) && height < (new_gray.rows-2))
{
double this_area = cv::contourArea(contours[i]);
if (this_area > max_contours_area)
{
max_contours_area = this_area;
}
}
}
for (int i = 0; i < contours.size(); i++)
{
cv::RotatedRect rectPoint2 = minAreaRect(contours[i]);
cv::Rect roi;
roi = rectPoint2.boundingRect();
int width = roi.width;
int height = roi.height;
if (width >= 3 && height >= 3 && width < (new_gray.cols-2) && height < (new_gray.rows-2))
{
double this_area = cv::contourArea(contours[i]);
if (this_area == max_contours_area)
{
cv::drawContours(to_draw, contours, i, cv::Scalar(0, 0, 255), 1.5, 8);
cv::Rect rroi = get_minroi(contours[i]);
cv::Mat to_return(new_gray, rroi);
cv::resize(to_return, to_return, cv::Size(30, 30));
cv::threshold(to_return, to_return, 80, 255, CV_THRESH_BINARY);
return to_return;
}
}
}
}
8:求角度
double no_1(float input);
double no_1(float input)
{
double k = fmod(input, 1.0);
return k * 360.0;
}
9:回归方程
//【a,b [t1
// c,d】 t2]
vector<float> regression(vector<cv::Point> input1, vector<cv::Point> input2);
vector<float> regression(vector<cv::Point> input1, vector<cv::Point> input2)
{
vector<float> x1;
vector<float> y1;
vector<float> x2;
vector<float> y2;
int size;
if (input1.size() > input2.size())
{
size = input2.size();
}
else
{
size = input1.size();
}
for (int i = 0; i < size; i++)
{
x1.push_back(input1[i].x);
x2.push_back(input2[i].x);
y1.push_back(input1[i].y);
y2.push_back(input2[i].y);
}
float a_0 = 0.0, a_1 = 0.0, a_2 = 0.0, a_3 = 0.0;
float b_0 = 0.0, b_1 = 0.0, b_2 = 0.0, b_3 = 0.0;
float c_0 = 0.0, c_1 = 0.0, c_2 = 0.0, c_3 = 0.0;
float d_0 = 0.0, d_1 = 0.0, d_2 = 0.0, d_3 = 0.0;
float a_x2 = 0.0;
float a_y2 = 0.0;
float a_x1 = 0.0;
float a_y1 = 0.0;
for (int i = 0; i < size; i++)
{
a_0 += x1[i] * x2[i];
b_0 += x1[i] * y2[i];
c_0 += y1[i] * x2[i];
d_0 += y1[i] * y2[i];
a_1 += x1[i] * x2[i];
b_1 += x1[i] * y2[i];
c_1 += y1[i] * x2[i];
d_1 += y1[i] * y2[i];
a_2 += x1[i] * x1[i];
b_2 += x1[i] * y1[i];
c_2 += x1[i] * y1[i];
d_2 += y1[i] * y1[i];
a_3 += x1[i] * x2[i];
b_3 += y1[i] * y2[i];
c_3 += x2[i] * y1[i];
d_3 += y1[i] * y2[i];
a_x2 += x2[i];
a_x1 += x1[i];
a_y2 += y2[i];
a_y1 += y1[i];
}
a_1 = a_1 / size;
b_1 = b_1 / size;
c_1 = c_1 / size;
d_1 = d_1 / size;
a_x1 = a_x1 / size;
a_x2 = a_x2 / size;
a_y1 = a_y1 / size;
a_y2 = a_y2 / size;
cout << "average x1 y1 " << a_x1 << " " << a_x2 << endl;
cout << "average x2 y2 " << a_x2 << " " << a_y2 << endl;
a_3 = a_3 / size;
b_3 = b_3 / size;
c_3 = c_3 / size;
d_3 = d_3 / size;
vector<float> to_return;
float a = 0.0, b = 0.0, c = 0.0, d = 0.0;
a = (a_0 - a_1) / (a_2 - a_3);
b = (b_0 - b_1) / (b_2 - b_3);
c = (c_0 - c_1) / (c_2 - c_3);
d = (d_0 - d_1) / (d_2 - d_3);
to_return.push_back(a);
to_return.push_back(b);
to_return.push_back(c);
to_return.push_back(d);
float t1 = 0.0;
float t2 = 0.0;
t1 = a_x2 - a*a_x1 - b*a_y1;
t2 = a_y2 - c*a_x1 - d*a_y1;
to_return.push_back(t1);
to_return.push_back(t2);
return to_return;
}
10 在选定区域内画点
void draw_new_from_old(cv::Mat old, cv::Rect new_one, vector<cv::KeyPoint>keypoints);
void draw_new_from_old(cv::Mat old, cv::Rect new_one, vector<cv::KeyPoint>keypoints)
{
for (int i = 0; i < keypoints.size(); i++)
{
cv::Point buffer;
buffer.x = int(keypoints[i].pt.x) + new_one.x;
buffer.y = int(keypoints[i].pt.y) + new_one.y;
cv::circle(old, buffer, 2, cv::Scalar(0, 0, 255));
}
}
11 中心点
cv::Point get_average_point(vector<cv::Point> input);
cv::Point get_average_point(vector<cv::Point> input)
{
int avg_x = 0;
int avg_y = 0;
for (int i = 0; i < input.size(); i++)
{
avg_x += input[i].x;
avg_y += input[i].y;
}
if (input.size() != 0)
{
avg_x = avg_x / (input.size());
avg_y = avg_y / (input.size());
}
cv::Point point(avg_x,avg_y);
return point;
}
12 重新组织矩形
cv::Rect orgnize_roi(vector<cv::Rect> input);
cv::Rect orgnize_roi(vector<cv::Rect> input)
{
int min_x = 1000;
int min_y = 1000;
int max_x = 0;
int max_y = 0;
for (int i = 0; i < input.size(); i++)
{
int this_x = input[i].x;
int this_y = input[i].y;
int this_x_w = input[i].x + input[i].width;
int this_y_h = input[i].y + input[i].height;
if (this_x > max_x)
{
max_x = this_x;
}
if (this_y > max_y)
{
max_y = this_y;
}
if (this_x < min_x)
{
min_x = this_x;
}
if (this_y < min_y)
{
min_y = this_y;
}
if (this_x_w > max_x)
{
max_x = this_x_w;
}
if (this_y_h > max_y)
{
max_y = this_y_h;
}
}
cv::Rect to_return;
to_return.x = min_x;
to_return.y = min_y;
to_return.width = max_x - min_x;
to_return.height = max_y - min_y;
return to_return;
}
13 删除相同的矩形
vector<cv::Rect> remove_same_roi(vector<cv::Rect> input);
vector<cv::Rect> remove_same_roi(vector<cv::Rect> input)
{
vector<int> count;
vector<cv::Rect> compare;
for (int i = 0; i < input.size(); i++)
{
int biaozhi = 0;
for (int j = 0; j < compare.size(); j++)
{
if (input[i].x == compare[j].x && input[i].y == compare[j].y)
{
if (input[i].width == compare[j].width && input[i].height == compare[j].height)
{
biaozhi = 1;
}
}
}
if (biaozhi != 1)
{
compare.push_back(input[i]);
}
}
return compare;
}
14 最大池化
cv::Mat max_pool(cv::Mat input, int stride = 10, int kernel_size = 20);
cv::Mat max_pool(cv::Mat input, int stride , int kernel_size)
{
int out_height = (input.rows - kernel_size) / stride;
int out_weight = (input.cols - kernel_size) / stride;
cv::Mat to_return(out_height + 1, out_weight + 1, CV_8UC1, cv::Scalar(0));
vector<uchar> kernel;
for (int i = 0; i + kernel_size < input.cols; i += stride)
{
for (int j = 0; j + kernel_size < input.rows; j += stride)
{
for (int k = 0; k < kernel_size; k++)
{
for (int l = 0; l < kernel_size; l++)
{
if ((j + l >= input.rows) || (i + k >= input.cols))
{
continue;
}
uchar* data = input.ptr<uchar>(j + l, i + k);
kernel.push_back(*data);
}
}
uchar min = compute_pow_max(kernel);
kernel.clear();
to_return.at<uchar>(j / stride, i / stride) = min;
}
}
return to_return;
}
15 数组删除相同元素
vector<int> remove_same_data(vector<int> input);
vector<int> remove_same_data(vector<int> input)
{
vector<int> compare;
for (int i = 0; i < input.size(); i++)
{
int biaozhi = 0;
for (int j = 0; j < compare.size(); j++)
{
if (compare[j] == input[i])
{
biaozhi = 1;
}
}
if (biaozhi != 1)
{
compare.push_back(input[i]);
}
}
return compare;
}