1英寸等于16mm ,但不能适用所有的尺寸,小于1/2英寸的CIS,则要用1英寸等于18mm来换算。比如索尼1/2.8 的IMX415 对角线长度为6.43mm,英1英寸等于18mm则刚好。所以对于海康等监控摄像头,使用1英寸等于18mm来计算对角线尺寸,然后再通过4:3 的比例计算物理的长宽尺寸。
18*1/2.8=6.429mm
4x*4x+3x*3x=6.429*6.429
按4:3,则长为5.143mm,则像元为5.143/1920=2.68um
一个无聊和记录一些东西的博客
1英寸等于16mm ,但不能适用所有的尺寸,小于1/2英寸的CIS,则要用1英寸等于18mm来换算。比如索尼1/2.8 的IMX415 对角线长度为6.43mm,英1英寸等于18mm则刚好。所以对于海康等监控摄像头,使用1英寸等于18mm来计算对角线尺寸,然后再通过4:3 的比例计算物理的长宽尺寸。
18*1/2.8=6.429mm
4x*4x+3x*3x=6.429*6.429
按4:3,则长为5.143mm,则像元为5.143/1920=2.68um
首先需要先在库文件的工程定义extern “c”
因为服务器所在网络环境原因,不得不需要离线安装python 依赖包
使用如下方法,只下载需要的依赖包:
python -m pip download -r requirements.txt -d 目录
这方法会自动下载依赖包的依赖包,然后整个打包到目标服务器,然后在解压包所在目录运行
python -m pip install –no-index –find-links=目录名 -r requirements.txt
完成
将docker容器保存为 tar 包
1、docker commit <容器id> <镜像名>:<tag> —- 将容器保存成镜像
保存后 docker images 便可以看到镜像
2、docker save -o <tar包名>.tar <镜像名>:<tag> —- 将镜像保存为.tar文件,默认保存在当前目录
· 从 tar 包导入docker镜像
1、docker load -i <tar包名>.tar —- 从 tar 包导入镜像
导入镜像后,通过 docker images 便可看到导入的镜像。
2、docker run -itd -p <本地端口>:<容器端口> <镜像名>:<tag> —- 通过镜像起容器
· 案例
1、docker commit 294oajfhfnci abcdef:latest —- 将294oajfhfnci容器保存为镜像abcdef
2、docker save -o abcdef.tar abcdef:latest —- 将镜像abcdef保存为abcdef.tar
3、docker load -i abcdef.tar —- 从 abcdef.tar 导入镜像
4、docker run -itd -p 8888:80 –restart=always abcdef:latest —- 通过abcdef镜像启动容器
————————————————
版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_54866636/article/details/126327700
因为服务器所在网络环境的原因,不得不在无法连接外网的环境下编译tensorflow 。过程有点痛苦,走了不少弯路,最后还是实现了。具体方法是,先在一台能连接互联网的机器上使用正常的方法用官方提供的bazel 编译一遍。然后,编译过程中他会自动下载所有需要的包到~/.cache/baxel/_bazel_(用户名)这个目录。(足足差不多10G!),然后把这个目录整个打包复制到不能连接外网的目标机器。放在相同目录下,注意目录需要改为当前用户名。然后把 tensorflow-2.11(源码所在目录)/tensorflow/ 里的 workspace 0 – 3. bzl 文件里的包改为本地目录位置,方法可以是,改为file://xxxxx/ 这样的方式,也可以是搭建一个web 服务,然后改为 http://xxxx/xxx.tar.gz 这样的方式。这个自行发挥了。最后他还有个提示,说有个什么目录文件存在,所以编译不了,直接把哪个目录删了就行。还有一个问题是他会提示验证golang sdk 版本,这个问题很奇怪,我试了两台机,一台不用管,直接跳过了。另一台是强行修改了一个sdk.bzl 文件,把他要打开的一个go 版本校验js 手工下载并改到这个sdk.bzl 文件里才能通过。这个看他提示照着办了。
bazel build –config=opt –local_cpu_resources=70 –local_ram_resources=8192 //tensorflow:libtensorflow_cc.so
其中 –local_cpu_resources=70 是使用CPU的核数,–local_ram_resources=8192 是使用内存数,为了使用多核CPU的多个核同时参与编译,须要加入–local_cpu_resources ,否则默认只使用单核,这样效率非常低。另外需要注意的是–local_ram_resources 这个参数不能太大,这个参数似乎并不是指总的利用内存数,而是单个进程在编译时使用的内存数,如果设得太大,会因为内存耗尽导致系统卡死。
(to train old Yolo v2 yolov2-voc.cfg
, yolov2-tiny-voc.cfg
, yolo-voc.cfg
, yolo-voc.2.0.cfg
, … click by the link)
Training Yolo v4 (and v3):
cfg/yolov4-custom.cfg
download the pre-trained weights-file (162 MB): yolov4.conv.137 (Google drive mirror yolov4.conv.137 )yolo-obj.cfg
with the same content as in yolov4-custom.cfg
(or copy yolov4-custom.cfg
to yolo-obj.cfg)
and:batch=64
subdivisions=16
classes*2000
, but not less than number of training images and not less than 6000
), f.e. max_batches=6000
if you train for 3 classessteps=4800,5400
width=416 height=416
or any value multiple of 32: https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L8-L9classes=80
to your number of objects in each of 3 [yolo]
-layers:
filters=255
] to filters=(classes + 5)x3 in the 3 [convolutional]
before each [yolo]
layer, keep in mind that it only has to be the last [convolutional]
before each of the [yolo]
layers.
[Gaussian_yolo]
layers, change [filters=57
] filters=(classes + 9)x3 in the 3 [convolutional]
before each [Gaussian_yolo]
layer
So if classes=1
then should be filters=18
. If classes=2
then write filters=21
. (Do not write in the cfg-file: filters=(classes + 5)x3)
(Generally filters
depends on the classes
, coords
and number of mask
s, i.e. filters=(classes + coords + 1)*<number of mask>
, where mask
is indices of anchors. If mask
is absence, then filters=(classes + coords + 1)*num
)
So for example, for 2 objects, your file yolo-obj.cfg
should differ from yolov4-custom.cfg
in such lines in each of 3 [yolo]-layers:
[convolutional]
filters=21
[region]
classes=2
obj.names
in the directory build\darknet\x64\data\
, with objects names – each in new lineobj.data
in the directory build\darknet\x64\data\
, containing (where classes = number of objects):classes = 2
train = data/train.txt
valid = data/test.txt
names = data/obj.names
backup = backup/
build\darknet\x64\data\obj\
It will create .txt
-file for each .jpg
-image-file – in the same directory and with the same name, but with .txt
-extension, and put to file: object number and object coordinates on this image, for each object in new line:
<object-class> <x_center> <y_center> <width> <height>
Where:
<object-class>
– integer object number from 0
to (classes-1)
<x_center> <y_center> <width> <height>
– float values relative to width and height of image, it can be equal from (0.0 to 1.0]
for example: <x> = <absolute_x> / <image_width>
or <height> = <absolute_height> / <image_height>
attention: <x_center> <y_center>
– are center of rectangle (are not top-left corner)
For example for img1.jpg
you will be created img1.txt
containing:
1 0.716797 0.395833 0.216406 0.147222
0 0.687109 0.379167 0.255469 0.158333
1 0.420312 0.395833 0.140625 0.166667
train.txt
in directory build\darknet\x64\data\
, with filenames of your images, each filename in new line, with path relative to darknet.exe
, for example containing:data/obj/img1.jpg
data/obj/img2.jpg
data/obj/img3.jpg
Download pre-trained weights for the convolutional layers and put to the directory build\darknet\x64
yolov4.cfg
, yolov4-custom.cfg
(162 MB): yolov4.conv.137 (Google drive mirror yolov4.conv.137 )yolov4-tiny.cfg
, yolov4-tiny-3l.cfg
, yolov4-tiny-custom.cfg
(19 MB): yolov4-tiny.conv.29csresnext50-panet-spp.cfg
(133 MB): csresnext50-panet-spp.conv.112yolov3.cfg, yolov3-spp.cfg
(154 MB): darknet53.conv.74yolov3-tiny-prn.cfg , yolov3-tiny.cfg
(6 MB): yolov3-tiny.conv.11enet-coco.cfg (EfficientNetB0-Yolov3)
(14 MB): enetb0-coco.conv.132Start training by using the command line: darknet.exe detector train data/obj.data yolo-obj.cfg yolov4.conv.137
To train on Linux use command: ./darknet detector train data/obj.data yolo-obj.cfg yolov4.conv.137
(just use ./darknet
instead of darknet.exe
)
yolo-obj_last.weights
will be saved to the build\darknet\x64\backup\
for each 100 iterations)yolo-obj_xxxx.weights
will be saved to the build\darknet\x64\backup\
for each 1000 iterations)darknet.exe detector train data/obj.data yolo-obj.cfg yolov4.conv.137 -dont_show
, if you train on computer without monitor like a cloud Amazon EC2)darknet.exe detector train data/obj.data yolo-obj.cfg yolov4.conv.137 -dont_show -mjpeg_port 8090 -map
then open URL http://ip-address:8090
in Chrome/Firefox browser)8.1. For training with mAP (mean average precisions) calculation for each 4 Epochs (set valid=valid.txt
or train.txt
in obj.data
file) and run: darknet.exe detector train data/obj.data yolo-obj.cfg yolov4.conv.137 -map
After training is complete – get result yolo-obj_final.weights
from path build\darknet\x64\backup\
darknet.exe detector train data/obj.data yolo-obj.cfg backup\yolo-obj_2000.weights
(in the original repository https://github.com/pjreddie/darknet the weights-file is saved only once every 10 000 iterations if(iterations > 1000)
)
Note: If during training you see nan
values for avg
(loss) field – then training goes wrong, but if nan
is in some other lines – then training goes well.
Note: If you changed width= or height= in your cfg-file, then new width and height must be divisible by 32.
Note: After training use such command for detection: darknet.exe detector test data/obj.data yolo-obj.cfg yolo-obj_8000.weights
Note: if error Out of memory
occurs then in .cfg
-file you should increase subdivisions=16
, 32 or 64: link
# coding: utf-8
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import os
os.environ[‘TF_CPP_MIN_LOG_LEVEL’] = ‘2’
mnist = input_data.read_data_sets(‘mnist_data’, one_hot=True)
#初始化过滤器
def weight_variable(shape):
return tf.Variable(tf.truncated_normal(shape, stddev=0.1))
#初始化偏置,初始化时,所有值是0.1
def bias_variable(shape):
return tf.Variable(tf.constant(0.1, shape=shape))
#卷积运算,strides表示每一维度滑动的步长,一般strides[0]=strides[3]=1
#第四个参数可选”Same”或”VALID”,“Same”表示边距使用全0填充
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding=”SAME”)
#池化运算
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding=”SAME”)
#创建x占位符,用于临时存放MNIST图片的数据,
# [None, 784]中的None表示不限长度,而784则是一张图片的大小(28×28=784)
x = tf.placeholder(tf.float32, [None, 784], name=’input’)
#y_存的是实际图像的标签,即对应于每张输入图片实际的值
y_ = tf.placeholder(tf.float32, [None, 10])
#将图片从784维向量重新还原为28×28的矩阵图片,
# 原因参考卷积神经网络模型图,最后一个参数代表深度,
# 因为MNIST是黑白图片,所以深度为1,
# 第一个参数为-1,表示一维的长度不限定,这样就可以灵活设置每个batch的训练的个数了
x_image = tf.reshape(x, [-1, 28, 28, 1])
#第一层卷积
#将过滤器设置成5×5×1的矩阵,
#其中5×5表示过滤器大小,1表示深度,因为MNIST是黑白图片只有一层。所以深度为1
#32表示我们要创建32个大小5×5×1的过滤器,经过卷积后算出32个特征图(每个过滤器得到一个特征图),即输出深度为64
W_conv1 = weight_variable([5, 5, 1, 32])
#有多少个特征图就有多少个偏置
b_conv1 = bias_variable([32])
#使用conv2d函数进行卷积计算,然后再用ReLU作为激活函数
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
#卷积以后再经过池化操作
h_pool1 = max_pool_2x2(h_conv1)
#第二层卷积
#因为经过第一层卷积运算后,输出的深度为32,所以过滤器深度和下一层输出深度也做出改变
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
#全连接层
#经过两层卷积后,图片的大小为7×7(第一层池化后输出为(28/2)×(28/2),
#第二层池化后输出为(14/2)×(14/2)),深度为64,
#我们在这里加入一个有1024个神经元的全连接层,所以权重W的尺寸为[7 * 7 * 64, 1024]
W_fc1 = weight_variable([7 * 7 * 64, 1024])
#偏置的个数和权重的个数一致
b_fc1 = bias_variable([1024])
#这里将第二层池化后的张量(长:7 宽:7 深度:64) 变成向量(跟上一节的Softmax模型的输入一样了)
h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
#使用ReLU激活函数
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
#dropout
#为了减少过拟合,我们在输出层之前加入dropout
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
#输出层
#全连接层输入的大小为1024,而我们要得到的结果的大小是10(0~9),
# 所以这里权重W的尺寸为[1024, 10]
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
#最后都要经过Softmax函数将输出转化为概率问题
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2, name=’output’)
#损失函数和损失优化
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv)))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
#测试准确率,跟Softmax回归模型的一样
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
#将训练结果保存,如果不保存我们这次训练结束后的结果也随着程序运行结束而释放了
savePath = ‘./mnist_conv/’
saveFile = savePath + ‘mnist_conv.ckpt’
if os.path.exists(savePath) == False:
os.mkdir(savePath)
saver = tf.train.Saver()
#开始训练
with tf.Session() as sess:
#初始化所有变量
sess.run(tf.global_variables_initializer())
#训练两万次
for i in range(20000):
#每次获取50张图片数据和对应的标签
batch = mnist.train.next_batch(50)
#每训练100次,我们打印一次训练的准确率
if i % 100 == 0:
train_accuracy =sess.run(accuracy, feed_dict={x:batch[0], y_:batch[1], keep_prob:1.0})
print(“step %d, training accuracy %g” % (i, train_accuracy))
#这里是真的训练,将数据传入
sess.run(train_step, feed_dict={x:batch[0], y_:batch[1], keep_prob:0.5})
print (“end train, start testing…”)
mean_value = 0.0
for i in range(mnist.test.labels.shape[0]):
batch = mnist.test.next_batch(50)
train_accuracy = sess.run(accuracy, feed_dict={x: batch[0], y_: batch[1], keep_prob: 1.0})
mean_value += train_accuracy
print(“test accuracy %g” % (mean_value / mnist.test.labels.shape[0]))
# #训练结束后,我们使用mnist.test在测试最后的准确率
# print(“test accuracy %g” % sess.run(accuracy, feed_dict={x:mnist.test.images, y_:mnist.test.labels, keep_prob:1.0}))
# 最后,将会话保存下来
saver.save(sess, saveFile)
使用PYTHON 调用tensorflow的GPU的一般方法如下:
physical_devices = tf.config.experimental.list_physical_devices(‘GPU’)
tf.config.experimental.set_memory_growth(physical_devices[0], True)
但这样有个问题,当主机有多个GPU时,会抛出一个错误,大致意思是不能使用不同GPU的显存。遇到这个问题,在百度上找到大多数的解决方法是,在这段代码之前加入如下:
os.environ[‘CUDA_VISIBLE_DEVICES’]=’0′
这样,代码是能正常运行了,但这样会有另一个问题,就是主机上明明有两个甚至更多的GPU,但程序只能使用其中一个运行,这大大浪费了主机的机能。之后,阅读了外国的社区和网站,看到遇到同样问题的技术人员的回复和解决方法,终于找到了最好的解决方法。修改GPU调用的代码如下:
例如有两个GPU
os.environ[‘CUDA_VISIBLE_DEVICES’]=’0,1′
physical_devices = tf.config.experimental.list_physical_devices(‘GPU’)
for gpu_instance in physical_devices:
tf.config.experimental.set_memory_growth(gpu_instance,True)
经测试,这样就可以同一个程序同时使用多个GPU处理了。
先说明一下这么干的背景。因为项目需要,视频需要转成可以直接在浏览器上播放的流格式,或者直接在浏览器显示的格式。浏览器使用的是FIREFOX 或者CHROME 之类的浏览器。另外,还需要极低的视频延迟,最好少于1秒的延迟。一开始走了不少弯路,海康摄像头本身支持RTSP 流协议,但经测试,使用这个协议取流的话,本身就有大约0.5秒到1秒的延迟,如果再对流作进一步的处理的话,就会产生约2秒或以上的延迟。最后,只有使用海康SDK的私有协议来取流。经测试,SDK私有协议取流是几乎没有延迟的,但海康SDK取流只有C++,所以,就有了C++调用SDK取视频流,再封装接口给PYTHON输出到浏览器这个做法。
C++核心部分的代码:
%module cam_midware_cc
%include <opencv.i>
%cv_instantiate_all_defaults
%{
#include “cam_midware_cc.h”
%}
%include “cam_midware_cc.h”