
1.配置树莓派
进入配置界面
sudo raspi-config
开启摄像头
设置显示大小
开启VNC服务
设置账号密码
账号:pi
密码:123
重启查看设备内存

剩余9G
2.测试摄像头
使用的是USB摄像头,在终端安装软件
sudo apt-get install fswebcam
拍照,测试摄像头
sudo fswebcam image.jpg

有点模糊,调一下焦距
安装motion
Sudo apt-get install motion
sudo nano /etc/default/motion
修改motion的配置文件
sudo vim /etc/motion/motion.conf
修改配置文件:
将第11行的daemon off 改成daemon on
该文件很长,需要一直往下翻,直到464行你才看到端口号8081,我们通过这个端口来读取视频数据,这里无需修改!如下图:
然后到第477行将stream_localhost on改成off,即关闭 localhost 的限制,如下图:
当然,你也可以设定图片的分辨率,在第90行进行修改:
启动motion
sudo service motion start
sudo motion
在浏览器打开
3.树莓派安装OPENCV
加速python pip下载速度
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip install pip -U
3.1、安装numpy
打开命令行界面,输入以下命令,安装Python科学计算库numpy
sudo pip3 install numpy
3.2、在树莓派设置中把根目录扩大到整个SD卡
命令行界面输入命令,进入树莓派配置界面。用上下键和左右键切换光标位置。
sudo raspi-config
树莓派配置界面
第七行:Advanced Options
Adcanved Options
选择Expand Filesystem,将根目录扩展到这个SD卡,充分利用SD卡的存储空间。如果不进行这一步,后续命令会出现卡死。退出设置界面,重启树莓派。
sudo reboot
3.3、安装OpenCV所需的库
挨个运行下面八条命令。共需要七分钟(注意倒数第三条命令中要安装四个-dev软件包)。
sudo apt-get install build-essential git cmake pkg-config -y
sudo apt-get install libjpeg8-dev -y
sudo apt-get install libtiff5-dev -y
sudo apt-get install libjasper-dev -y
sudo apt-get install libpng12-dev -y
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev -y
sudo apt-get install libgtk2.0-dev -y
sudo apt-get install libatlas-base-dev gfortran -y
3.4、下载OpenCV
在命令行输入以下三条命令,下载两个压缩包到树莓派的/home/pi/Downloads目录下。第一个压缩包86.8MB,第二个压缩包54.5MB:
cd /home/pi/Downloads
wget https://github.com/Itseez/opencv/archive/3.4.0.zip
wget https://github.com/Itseez/opencv_contrib/archive/3.4.0.zip
下载之后,把第一个压缩包重新命名为opencv-3.4.0.zip,把第二个压缩包重新命名为opencv_contrib-3.4.0.zip
如果下载速度很慢(比如每秒几个KB):
方法1:可以在电脑浏览器中输入wget后面的链接下载压缩包,再用Fillzilla或者U盘等方法把文件传输到树莓派的/home/pi/Downloads目录下(一定不能错)。
方法2::可以用电脑在百度网盘链接下载这两个压缩包之后再用Fillzilla或者U盘等方法把文件传输到树莓派的/home/pi/Downloads目录下(一定不能错)。

解压这两个压缩包
cd /home/pi/Downloads
unzip opencv-3.4.0.zip
unzip opencv_contrib-3.4.0.zip
设置编译参数
设置编译参数
cd /home/pi/Downloads/opencv-3.4.0
mkdir build
cd build
设置CMAKE参数,注意,下面这是一行命令(包括最后那俩点儿),需要耐心等待十五分钟左右:
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D OPENCV_EXTRA_MODULES_PATH=/home/pi/Downloads/opencv_contrib-3.4.0/modules -D BUILD_EXAMPLES=ON -D WITH_LIBV4L=ON PYTHON3_EXECUTABLE=/usr/bin/python3.5 PYTHON_INCLUDE_DIR=/usr/include/python3.5 PYTHON_LIBRARY=/usr/lib/arm-linux-gnueabihf/libpython3.5m.so PYTHON3_NUMPY_INCLUDE_DIRS=/home/pi/.local/lib/python3.5/site-packages/numpy/core/include ..
根据下图判断你是否配置成功了CMAKE。如果失败,可能是因为两个压缩包的路径没有严格按照上文的要求。如果成功,就可以开始最重要的编译了。

3.5、编译
最后一步,也是最重要的一步:编译
保证树莓派有至少5G的存储空间,建议本命令用树莓派桌面上的命令行工具运行,而不要使用远程ssh连接。因为执行命令时间太长,中途如果ssh断线的话无法得知是否已经安装完毕。
cd /home/pi/Downloads/opencv-3.4.0/build
make
开始编译
如果遇上错误:make[2]: *** [modules/python3/CMakeFiles/opencv_python3.dir/build.make:56: modules/python3/CMakeFiles/opencv_python3.dir/__/src2/cv2.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:21149: modules/python3/CMakeFiles/opencv_python3.dir/all] Error 2
make: *** [Makefile:138: all] Error 2
找到cv2.cpp那个文件
texteditor打开,翻到885行(可能每个人的不一样,就在这附近)
前面要加上个(char *)。
然后再编译,在这个地方停很长时间就可以通过了。
编译完成
make命令执行完成之后,执行下面的命令,执行命令需要一分钟:
sudo make install
安装好之后,在命令行中输入python3,回车
import cv2
回车
cv2.version
回车
如果出现下图的结果,说明Python3环境下的OpenCV安装成功。
Python3的OpenCV安装完成
如果报错
ImportError: /usr/local/lib/python3.7/dist-packages/cv2/cv2.cpython-37m-arm-linux-gnueabihf.so: undefined symbol: __atomic_fetch_add_8
nano /etc/profile
export LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1
source /etc/profile
4.树莓派拍摄图片
源码实现
import cv2
#获取摄像头
cap=cv2.VideoCapture(0)
while(1):
#从摄像头读取一帧图片
ret ,frame = cap.read()
k=cv2.waitKey(1)
#输入ESC退出程序
if k==27:
break
#输入s保存图片
elif k==ord('s'):
cv2.imwrite("out.png",frame)
cv2.imshow("capture", frame)
#释放摄像头
cap.release()
cv2.destroyAllWindows()
代码很简单,就是调用摄像头,输入s拍一张图片。
使用方法
- 第一次使用的时候
输入:source /etc/profile
配置一下环境变量
- 在/home/pi目录内,打开video.py
python video.py
这个时候,能开始显示视频流
输入按键s,保存一张图片,输入esc按键,退出程序

5.座滴法


6.座滴法测量角度的实现
从上一节知道,通过椭圆的半径和高可以得到接触角的正弦值,这里使用查表法,转换出角度
#正弦值转换表(0~90度)
angle_array = [
[0, 0],
[1, 0.017452],
[2, 0.034899],
[3, 0.052336],
[4, 0.069756],
[5, 0.087156],
[6, 0.104528],
[7, 0.121869],
[8, 0.139173],
[9, 0.156434],
[10, 0.173648],
[11, 0.190809],
[12, 0.207912],
[13, 0.224951],
[14, 0.241922],
[15, 0.258819],
[16, 0.275637],
[17, 0.292372],
[18, 0.309017],
[19, 0.325568],
[20, 0.34202] ,
[21, 0.358368],
[22, 0.374607],
[23, 0.390731],
[24, 0.406737],
[25, 0.422618],
[26, 0.438371],
[27, 0.45399] ,
[28, 0.469472],
[29, 0.48481] ,
[30, 0.5] ,
[31, 0.515038],
[32, 0.529919],
[33, 0.544639],
[34, 0.559193],
[35, 0.573576],
[36, 0.587785],
[37, 0.601815],
[38, 0.615661],
[39, 0.62932] ,
[40, 0.642788],
[41, 0.656059],
[42, 0.669131],
[43, 0.681998],
[44, 0.694658],
[45, 0.707107],
[46, 0.71934] ,
[47, 0.731354],
[48, 0.743145],
[49, 0.75471] ,
[50, 0.766044],
[51, 0.777146],
[52, 0.788011],
[53, 0.798636],
[54, 0.809017],
[55, 0.819152],
[56, 0.829038],
[57, 0.838671],
[58, 0.848048],
[59, 0.857167],
[60, 0.866025],
[61, 0.87462] ,
[62, 0.882948],
[63, 0.891007],
[64, 0.898794],
[65, 0.906308],
[66, 0.913545],
[67, 0.920505],
[68, 0.927184],
[69, 0.93358] ,
[70, 0.939693],
[71, 0.945519],
[72, 0.951057],
[73, 0.956305],
[74, 0.961262],
[75, 0.965926],
[76, 0.970296],
[77, 0.97437] ,
[78, 0.978148],
[79, 0.981627],
[80, 0.984808],
[81, 0.987688],
[82, 0.990268],
[83, 0.992546],
[84, 0.994522],
[85, 0.996195],
[86, 0.997564],
[87, 0.99863] ,
[88, 0.999391],
[89, 0.999848],
[90, 1]]
测量之前,需要先用鼠标在图片上确定三个点,分别是液滴与水平面两侧的位置以及液滴的高度
代码如下:
#鼠标触发操作
def draw_point(event,x,y,flags,param):
global mouse_down
global inputCount,x1,y1,x2,y2,x3,y3
if event == cv2.EVENT_LBUTTONDOWN:
mouse_down = True
# Check if mouse button was pressed
if event == cv2.EVENT_LBUTTONUP and mouse_down:
mouse_down = False
#椭圆左侧定位
if inputCount==0:
x1 = x
y1 = y
#椭圆右侧定位
elif inputCount==1:
x2 = x
y2 = y
#椭圆顶部定位
elif inputCount==2:
x3 = x
y3 = y
inputCount = inputCount + 1
if(inputCount > 2):
inputCount = 0
如果检测到鼠标输入,将当前鼠标的坐标存起来,一共是三次触发,第三次操作之后,重新回到第一次的状态
在主函数里面,首先加载一张名为p1.png的图片
img = cv2.imread("p1.png") #加载图片
实时检测鼠标输入变量,对每个变量做对应显示
#输入提示
if inputCount == 0:
cv2.putText(img, "left", (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
elif inputCount==1:
cv2.putText(img, "right", (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
elif inputCount==2:
cv2.putText(img, "top", (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
提示下一步操作是什么
当最后一次输入完成的时候
开始角度的计算
# 起点和终点的坐标
ptStart = (x1, y1)
ptEnd = (x2, y1)
cv2.line(img, ptStart, ptEnd, (255, 0, 0), thickness, lineType)
ptStart = (math.floor((x2 + x1)/2), y1)
ptEnd = (math.floor((x2 + x1)/2), y3)
cv2.line(img, ptStart, ptEnd, (0, 255, 0), thickness, lineType)
#计算出椭圆的半径和高度
r = math.floor((x2-x1)/2)
h = (y1-y3)
首先绘制出椭圆的长轴和短轴,计算出半径和高度
通过座滴法计算出正弦值
#计算正弦值
sin = (2*h*r)/((r*r)+(h*h))
再使用查表法计算出对应角度
#显示角度位置
cos = math.sqrt(1-(sin*sin))
tan = sin/cos
angle_top = r*tan
ptStart = (x1, y1)
ptEnd = (math.floor((x2 + x1)/2), math.floor(y1-angle_top))
cv2.line(img, ptStart, ptEnd, (0, 0, 255), thickness, lineType)
#查表计算角度
for index in range(0,88):
#显示出实际的角度
if(angle_array[index][1] == sin):
cv2.putText(img, "angle:"+str(angle_array[index][0]), (10, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
break
elif ((angle_array[index][1] <= sin) and (angle_array[index+1][1] >=sin )):
cv2.putText(img, "angle:"+str(angle_array[index][0]), (10, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
break
#显示正弦值
cv2.putText(img, "sin(x):"+str(sin), (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
为了确定测量的角度是不是准确,对测量位置做显示
# 绘制一个绿色椭圆
ptCenter = (math.floor((x2 + x1)/2), y1) # 中心点位置
axesSize = (r, h) # 长轴半径为 90,短轴半径为 60
rotateAngle = 0 # 旋转角度为 0
startAngle = 0
endAngle = 360
cv2.ellipse(img, ptCenter, axesSize, rotateAngle, startAngle, endAngle,(0, 255, 255) , thickness, lineType)
7.角度测量使用方法
将拍摄的图片,重命名为p1.png
在终端输入python angle.py,打开程序
观察左上角,显示的left,用鼠标点击液滴与桌面的左侧接触点

观察左上角,显示的right,用鼠标点击液滴与桌面的右侧接触点

观察左上角,显示的top,用鼠标点击液滴顶点

观察左上角。计算出角度为65度,通过座滴法计算出来的接触角正弦值是0.909