目前所处理的图片全都是单指针圆盘图像,一个图里可能出现1-2个表,但是项目任务谈的是每个摄像头大概要拍摄3-4个表(但是到时候摄像头位置会很好,直接切开每个图就行)
从以下图片可以看出,首先,光线和角度变化不是非常大。
这里要记住一点:
opencv中图像的x,y 坐标以及 height, width,rows,cols 他们的关系经常混淆。
rows 其实就是行,一行一行也就是y 啦。height高度也就是y啦。
cols 也就是列,一列一列也就是x啦。width宽度也就是x啦。
配合以下代码,以下图为例(这是一张640*604的图片):
cols和rows这个概念是 C++ 版本的opencv中有mat这种数据类型时涉及的,例如
Mat logo = imread("smile.png")
logo.cols, logo.rows
在计算机中,图像是以矩阵的形式保存的,先行后列。所以,一张 宽×高×颜色通道=480×256×3 的图片会保存在一个 256×480×3 的三维张量中
numpy的一般就是
>>> a = np.zeros((3,5))
>>> a
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
//可以看到这是3行5列 即 3是高度 5是宽度。即
//numpy的shape[0:2]和opencv中通过imread读取的图像的shape[0:2]是一样的的,即 (高度,宽度).
// 单凡涉及到size(包括cv2.resize 其约定的顺序 都是 宽度 x *高度 y)
# 也可以考虑直接自己造一个图片
from PIL import Image
img=np.zeros(shape=(100,200,3))
cv2.imshow('small_pic',img)
img=np.zeros(shape=(100,200,3))
# show_img(img,'img')
imgPIL=Image.fromarray(img.astype('uint8')).convert('RGB')
# imgPIL.show()
print(imgPIL.size)
上述numpy创造的图像使用opencv显示,可以看出,
- numpy的shape[0:2]和opencv中通过imread读取的图像的shape[0:2]是一样的的,即 (高度,宽度).
- 但凡涉及到size(包括cv2.resize 其约定的顺序 都是 宽度*高度),比如PIL的Image的size属性,以及resize里的fx和fy的书写。
由于某些原始的大图尺寸为3200*1800,已经超过我电脑的分辨率,所以最开始使用cv2.imshow()
的时候显示的图像不完全,根据参考[1],进行以下修改:
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
当遇到图像太大需要加入进度条或者需要手动调节窗口大小的时候,可以使用如下方式:
cv2支持先创建一个窗口在load图像,所以可以使用函数cv2.namedWindow()
明确窗口是否尺寸可变,默认情况下,函数cv2.namedWindow()
的flag值为cv2.WINDOW_AUTOSIZE
,也可以修改为cv2.WINDOW_NORMAL
,后者允许我们自己调节窗口大小。
这属于Opencv功能里的 » Image Processing in OpenCV » Geometric Transformations of Images
resize函数的原型:
cv::resize (InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR)
img = cv2.imread('messi5.jpg')
res = cv2.resize(img,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC)
#OR
height, width = img.shape[:2]
# img.shape(height width channel(RGB 3通道 灰度图 单通道))
res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)
# 我想要实现的是,固定高度,宽度按比例变化,则需要使用缩放因子 上述的fx(factor x 水平轴 dsize.width/src.cols fx 图像长度缩放因子 fy 图像宽度缩放因子)
height=600
width=img.shape[0]/600*img.shape[1]
如果是在jupyter notebook中的话,jupyter的ipywidget组件支持一些自定义滑块,可以帮助快速调节查看效果,后期考虑添加进去,快速进行调参(勉强算调参吧)
滤波器(图上确实存在一些 很零散的白色斑点/亮斑/噪声):Opencv官网说明
void cv::medianBlur ( InputArray src,
OutputArray dst,
int ksize
)
Python:
dst = cv.medianBlur( src, ksize[, dst] )
void cv::bilateralFilter ( InputArray src,
OutputArray dst,
int d,
double sigmaColor,
double sigmaSpace,
int borderType = BORDER_DEFAULT
)
Python:
dst = cv.bilateralFilter( src, d, sigmaColor, sigmaSpace[, dst[, borderType]])
cv2.bilateralFilter(img, 9, 50, 50)
// 这里的 三个数字分别对应 9 50 50
三个参数的大意分别是:
d滤波期间使用的每个像素邻域的直径。 如果它不是正值,则从sigmaSpace计算得出。
sigmaColor在色彩空间中过滤sigma。 参数的较大值表示像素邻域内的其他颜色(请参见sigmaSpace)将混合在一起,从而导致较大区域的半均等颜色。
sigmaSpace在坐标空间中过滤sigma。 该参数的值越大,表示越远的像素就会相互影响,只要它们的颜色足够接近即可(请参见sigmaColor)。 当d> 0时,它指定邻域大小,而不考虑sigmaSpace。 否则,d与sigmaSpace成比例。
ksize 必须是整数且是奇数
sigmaX,sigmaY即x,y方向上的高斯分布的标准差
void cv::GaussianBlur ( InputArray src,
OutputArray dst,
Size ksize,
double sigmaX,
double sigmaY = 0,
int borderType = BORDER_DEFAULT
)
Python:
dst = cv.GaussianBlur( src, ksize, sigmaX[, dst[, sigmaY[, borderType]]] )
综上,
根据opencv二值化的cv2.threshold函数可知,常用于二值化的函数有两个,如下:
cv2.threshold (src, thresh, maxval, type)
,选取一个全局阈值,然后就把整幅图像分成了非黑即白的二值图像了,其四个参数的含义为:第一个原图像,第二个进行分类的阈值,第三个是高于(低于)阈值时赋予的新值,第四个是一个方法选择参数
由于Opencv显示多图目前比较常见方法就是把图都拼接在一起,然后放到一个窗口进行显示,所以简单起见,还是使用matplotlib通过subplot显示多图