部分完整代码在
opencv example
addWeighted( src1, alpha, src2, beta, 0.0, dst);
代表
d s t = α × s r c 1 + β × s r c 2 + γ dst =\alpha \times src1 + \beta\times src2 + \gamma dst=α×src1+β×src2+γ
在本例子中
g a m m a = 0 , s r c 1 , s r c 2 代 表 两 幅 不 同 图 片 gamma=0, src1, src2代表两幅不同图片 gamma=0,src1,src2代表两幅不同图片
g ( i , j ) = α ∗ f ( i , j ) + β g(i, j) = \alpha * f(i, j) + \beta g(i,j)=α∗f(i,j)+β
for( int y = 0; y < image.rows; y++ ) {
for( int x = 0; x < image.cols; x++ ) {
for( int c = 0; c < image.channels(); c++ ) {
new_image.at(y,x)[c] =
saturate_cast( alpha*image.at(y,x)[c] + beta );
//saturate_cast防止灰度值溢出
}
}
}
采用look up table方法的话
Mat lookUpTable(1, 256, CV_8U);
uchar* p = lookUpTable.ptr();
for( int i = 0; i < 256; ++i)
p[i] = saturate_cast(i*alpha + beta);
Mat res = img.clone();
LUT(img, lookUpTable, res);
RNG rng;
b = rng; //产生64位整数
x = rng.uniform(a, b); //产生a,b 之间的一个值
y = rng.gaussian(sigma); //产生一个方差为sigma 均值位0满足高斯分布的值
blur( src, dst, Size( 3, 3 ), Point(-1,-1) );
GaussianBlur( src, dst, Size( 3, 3 ), 0, 0 );
//Size必须是奇数,否则要根据x, y方向的方差计算Size
medianBlur ( src, dst, i );
//中值滤波滤波器必须位正方形
bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )
//d 表示在过滤过程中每个像素邻域的直径范围
//sigmaColor: 颜色空间过滤器的sigma值,这个参数的值大,表明该像素邻域内有月宽广的颜色会被混合到一起
//sigmaSpace:坐标空间中滤波器的sigma值,如果该值较大,则意味着颜色相近的较远的像素将相互影响
###图像金字塔,包括高斯金字塔和laplace金字塔,实现上采样和下采样
pyrUp( src, src, Size( src.cols*2, src.rows*2 ) //上采样
pyrDown( src, src, Size( src.cols/2, src.rows/2 ) )//下采样
threshold ( InputArray src, OutputArray dst, double thresh, double maxval, int type )
Sobel(src_gray, grad_x, ddepth, 1, 0, ksize, scale, delta, BORDER_DEFAULT);
Sobel(src_gray, grad_y, ddepth, 0, 1, ksize, scale, delta, BORDER_DEFAULT);
convertScaleAbs(grad_x, abs_grad_x);
convertScaleAbs(grad_y, abs_grad_y);
addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT );
Canny( soure_img, edges, lowThreshold, highThreshold, kernel_size );
霍夫变换的远离参照opencv官网,在这里不加赘述https://docs.opencv.org/master/d9/db0/tutorial_hough_lines.html
opencv中提供了两种计算霍夫变换的方法
//霍夫变换针对二值图像```
Canny( soure_img, edges, lowThreshold, highThreshold, kernel_size );
//存储霍夫变换输出结果
vector lines;
//参数含义为原图像,结果, 参数r分辨率, theta分辨率 CV_PI/180代表1度, 检测是一根线阈值即有多少个点共线才算一条直线, 两个默认参数
HoughLines(dst, lines, 1, CV_PI/180, 150, 0, 0 ); // runs the actual detection
//绘图
// size_t是一种数据相关的无符号类型,它被设计得足够大以便能够内存中任意对象的大小
for( size_t i = 0; i < lines.size(); i++ )
{
float rho = lines[i][0], theta = lines[i][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));
line( cdst, pt1, pt2, Scalar(0,0,255), 3, LINE_AA);
}
//中间加上了1000的是因为HoughLines相当于返回了直线的斜率和常数,需要找出直线上两个点,这里相当于取了间隔为2000的两个点
概率霍夫变换代码
//存储输出结果
vector linesP;
//最后三个阈值含义 第一个是多少个点位于同一条直线;第二个是直线的最短长度;第三个是两天直线的gap
HoughLinesP(dst, linesP, 1, CV_PI/180, 50, 50, 10 );
//绘图
for( size_t i = 0; i < linesP.size(); i++ )
{
Vec4i l = linesP[i];
line( cdstP, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, LINE_AA);
}
void HoughCircles(InputArray image,OutputArray circles, int method, double dp, double minDist, double param1=100, double param2=100, int minRadius=0,int maxRadius0 )
// circles 包括 x,y, r
// method 目前只有HOUGH_GRADIENT一种
// dp=1 表示霍夫空间和原图分辨率一致, dp=2为一半 以此类推
// minDist eg gray.rows/16 检测出圆心最小距离
// param1 Canny edge detector阈值
// param2 有多少个点位于该圆阈值
// min_radius, max_radius 半径最大最小
a example:
HoughCircles(gray, circles, HOUGH_GRADIENT, 1,
gray.rows/16,
100, 30, 1, 30)
//画圆圈函数
cvCircle(CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int lineType=8, int shift=0)
//color定义 Scalar(B, G, R)
//shift小数点位数