[openCV 函数笔记] C++与Python

1. calcHist函数详解

calcHist计算直方图

(1)C++调用形式:

void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )

参数详解:
onst Mat* images:输入图像

int nimages:输入图像的个数

const int* channels:需要统计直方图的第几通道

InputArray mask:掩膜,,计算掩膜内的直方图 …Mat()

OutputArray hist:输出的直方图数组

int dims:需要统计直方图通道的个数

const int* histSize:指的是直方图分成多少个区间,就是 bin的个数

const float** ranges: 统计像素值得区间

bool uniform=true::是否对得到的直方图数组进行归一化处理

bool accumulate=false:在多个图像时,是否累计计算像素值得个数

(2)Python 调用形式:

cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) #返回hist

参数详解:
第一个参数必须用方括号括起来。

第二个参数是用于计算直方图的通道,这里使用灰度图计算直方图,所以就直接使用第一个通道;

第三个参数是Mask,这里没有使用,所以用None。

第四个参数是histSize,表示这个直方图分成多少份(即多少个直方柱)。第二个例子将绘出直方图,到时候会清楚一点。

第五个参数是表示直方图中各个像素的值,[0.0, 256.0]表示直方图能表示像素值从0.0到256的像素。

最后是两个可选参数,由于直方图作为函数结果返回了,所以第六个hist就没有意义了(待确定) 最后一个accumulate是一个布尔值,用来表示直方图是否叠加。

2. 傅里叶变换 openCV / numpy

将时域转换为频域,在频域上对图像进行操作。

(1)numpy 进行傅里叶变化 :

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('car.jpg', 0)

#numpy
f = np.fft.fft2(img) #傅里叶变换
fshift = np.fft.fftshift(f) #把中点移动到中间去

magnitude_spectrum = 20 * np.log(np.abs(fshift)) #计算每个频率的成分多少

plt.figure(figsize=(10, 10))
plt.subplot(221), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])

#去掉低频信号,留下高频信号
rows, cols = img.shape
crow, ccol = rows // 2, cols // 2
fshift[crow - 30:crow + 30, ccol - 30:ccol + 30] = 0


#傅里叶逆变换
f_ishift = np.fft.ifftshift(fshift)
img_back = np.fft.ifft2(f_ishift)
img_back = np.abs(img_back)

plt.subplot(223), plt.imshow(img_back, cmap='gray')
plt.title('Image after HPF'), plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(img_back)
plt.title('Result in JET'), plt.xticks([]), plt.yticks([])

plt.show()

(2)openCV 进行傅里叶变化 ;

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('car.jpg', 0)

dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)

magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))

plt.figure(figsize=(10, 10))
plt.subplot(221), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])

rows, cols = img.shape
crow, ccol = rows // 2, cols // 2
# create a mask first, center square is 1, remaining all zeros
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1
fshift = dft_shift * mask
# apply mask and inverse DFT

f_ishift = np.fft.ifftshift(fshift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])

plt.subplot(223), plt.imshow(img_back, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(img_back)
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])

plt.show()

代码结果

3. 霍夫变换Hough

根据数学公式,找出图像中对应的形状。(极坐标/直角坐标转换为霍夫空间,再根据数学公式找到符合的形状)

(1)python:

检测直线:cv2.HoughLines(edges, 1, np.pi/180,200)
第一个参数为 边缘提取后的图像

第二、三个参数分别为ρ和θ 的取值精度(极坐标)

第四个参数为阈值(多长的断裂范围判断为同一直线)

检测圆:circle = cv2.HoughCircles(dst, cv2.HOUGH_GRADIENT, 1, 80, param1=40, param2=20, minRadius=20, maxRadius=300)

第一个参数为待检测的图

第二个参数为Hough 变换方式,目前只支持CV_HOUGH_GRADIENT, which is basically 21HT, described in [Yuen03].

第三个参数为累加器图像的分辨率

第四个参数为区分的两个不同圆之间的最小距离

第五、六个参数为双边阈值的参数

第七、八个参数为检测的圆半径范围

(2)C++调用形式:

void HoughLines( InputArray image, 
                 OutputArray lines,
                 double rho,  // rho 的步长
                 double theta, // 角度步长
                 int threshold, // 阈值
                 double srn=0, 
                 double stn=0 );
void HoughCircles(InputArray image,
				OutputArray circles,
				int method, 
				CV_HOUGH_GRADIENT,
				double dp,
				double minDist,
				double param1=100,
				double param2=100, 
				int minRadius=0,
				int maxRadius=0  );

实例1:(Python 霍夫变换检测直线)

import cv2
import numpy as np

image = cv2.imread("lines.jpg")
image_2 = image.copy()

image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

edges = cv2.Canny(image_gray, 100, 150)

lines = cv2.HoughLines(edges, 1, np.pi / 180, 150)

for line in lines:
    rho, theta = line[0]
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a * rho
    y0 = b * rho
    x1 = int(x0 + 1000 * (-b))  # 直线起点横坐标
    y1 = int(y0 + 1000 * (a))  # 直线起点纵坐标
    x2 = int(x0 - 1000 * (-b))  # 直线终点横坐标
    y2 = int(y0 - 1000 * (a))  # 直线终点纵坐标
    cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)

imgs = np.hstack([image_2,image])
cv2.imshow("image_lines", imgs)
cv2.imwrite("test.jpg",imgs)

cv2.waitKey(0)

左边原图,右边检测后的图
实例2:(Python 霍夫变换检测圆)


import cv2
import numpy as np

rawImage = cv2.imread("circles.jpg")
image = cv2.GaussianBlur(rawImage, (3, 3), 1)
image_gray = cv2.cvtColor(image, cv2.COLOR_BGRA2GRAY)

edges = cv2.Canny(image_gray, 100, 150)


circle = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1, 80, param1=40, param2=20, minRadius=20, maxRadius=100)
if not circle is None:
    circle = np.uint16(np.around(circle))
    for i in circle[0, :]:
        cv2.circle(image, (i[0], i[1]), i[2], (0, 0, 255), 2)

imgs = np.hstack([rawImage,image])
cv2.imshow("image_lines", imgs)
cv2.imwrite("test.jpg",imgs)

cv2.waitKey(0)

左边原图,右边检测后的图

4.二值化/阈值操作

根据阈值将图像转化为二值图片。

(1)普通二值化

Python 函数形式:

 cv2.threshold(src, thresh, maxval, type[, dst]) → retval, dst

src:表示的是待转化的图片
thresh:表示的是阈值(起始值)
maxval:表示的是最大值
type:表示的是这里划分的时候的算法,常用值为0(cv2.THRESH_BINARY)

C++ 函数形式:

double cv::threshold(  
    cv::InputArray src, // 输入图像  
    cv::OutputArray dst, // 输出图像  
    double thresh, // 阈值  
    double maxValue, // 向上最大值  
    int thresholdType // 阈值化操作的类型   
);  

(2)自适应二值化

Python 函数形式:

cv2.adaptiveThreshold(src, maxval, thresh_type, type, Block Size, C) → retval, dst

src: 输入图,只能输入单通道图像,通常来说为灰度图
maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
thresh_type: 阈值的计算方法,包含以下2种类型:cv2.ADAPTIVE_THRESH_MEAN_C; cv2.ADAPTIVE_THRESH_GAUSSIAN_C.
type:二值化操作的类型,与固定阈值函数相同,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV.
Block Size: 图片中分块的大小
C :阈值计算方法中的常数项

C++ 函数形式:

void cv::adaptiveThreshold(
	cv::InputArray src, // 输入图像
	cv::OutputArray dst, // 输出图像
	double maxValue, // 向上最大值
	int adaptiveMethod, // 自适应方法,平均或高斯
	int thresholdType // 阈值化类型
	int blockSize, // 块大小
	double C // 常量
);

5. 仿射变换

仿射变换:平移、旋转、放缩、剪切、反射。

(1) Python 函数形式:

cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst

src - 输入图像。
M - 变换矩阵。
dsize - 输出图像的大小。
flags - 插值方法的组合(int 类型!)
borderMode - 边界像素模式(int 类型!)
borderValue - (重点!)边界填充值; 默认情况下,它为0。

(2)C++ 函数形式

void cv::warpAffine(cv::InputArray src, cv::OutputArray dst, cv::InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())

(3)变换矩阵

Python:

 rot_mat =  cv2.getRotationMatrix2D(center, -5, 1)

第一个参数表示旋转中间点的位置,
第二个参数表示旋转的度数,(逆时针旋转5度)
第三个参数表示进行等比列的缩放
C++:

Mat getRotationMatrix2D(Point2f center, double angle, double scale)

6.透视变换

透视变换是将图片投影到一个新的视平面,也称作投影映射。

(1)Python 函数形式:

生成透视变换矩阵 M:输入原始图像和变换之后的图像的对应4个点,便可以得到变换矩阵。

M = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.warpPerspective(img, M, (200, 201))

(2)C++ 函数形式:

Mat getPerspectiveTransform(const Point2f* src, const Point2f* dst)
cv::warpPerspective( InputArray src, 
 				 OutputArray dst,
 				 InputArray M, 
 				 Size dsize,
 				 int flags = INTER_LINEAR,
 				 int borderMode = BORDER_CONSTANT,
 				 const Scalar& borderValue = Scalar());

7.图像基本运算

(1)C++:(Python 同)

void add(InputArray src1, InputArray src2, OutputArray dst,InputArray mask=noArray(), int dtype=-1);//dst = src1 + src2
void subtract(InputArray src1, InputArray src2, OutputArray dst,InputArray mask=noArray(), int dtype=-1);//dst = src1 - src2
void multiply(InputArray src1, InputArray src2,OutputArray dst, double scale=1, int dtype=-1);//dst = scale*src1*src2
void divide(InputArray src1, InputArray src2, OutputArray dst,double scale=1, int dtype=-1);//dst = scale*src1/src2
void divide(double scale, InputArray src2,OutputArray dst, int dtype=-1);//dst = scale/src2
void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst);//dst = alpha*src1 + src2
void addWeighted(InputArray src1, double alpha, InputArray src2,double beta, double gamma, OutputArray dst, int dtype=-1);//dst = alpha*src1 + beta*src2 + gamma
void sqrt(InputArray src, OutputArray dst);//计算每个矩阵元素的平方根
void pow(InputArray src, double power, OutputArray dst);//src的power次幂
void exp(InputArray src, OutputArray dst);//dst = e**src(**表示指数的意思)
void log(InputArray src, OutputArray dst);//dst = log(abs(src))
void bitwise_and(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray());//dst = src1 & src2
void bitwise_or(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray());//dst = src1 | src2
void bitwise_xor(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray());//dst = src1 ^ src2
void bitwise_not(InputArray src, OutputArray dst,InputArray mask=noArray());//dst = ~src

(3)应用实例:掩膜(mask)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值