首先客户端是用qt,不能用python这种。
首先在pro里面
QT += network
然后引入头文件
#include <QTcpSocket>
#include <QHostAddress>
定义一个客户端的类
QTcpSocket *client;
然后定义一个函数,是将cv的Mat类型转换为QByteArray
QByteArray mat_to_QBytearray(cv::Mat data);
函数实现如下
QByteArray MainWindow::mat_to_QBytearray(cv::Mat data)
{
QImage Img;
if(data.channels() == 3)
{
cv::Mat Rgb;
cv::cvtColor(data, Rgb, CV_BGR2RGB);//颜色空间转换
Img = QImage((const uchar*)(Rgb.data), Rgb.cols, Rgb.rows, Rgb.cols * Rgb.channels(), QImage::Format_RGB888);
}
else
{
Img = QImage((const uchar*)(data.data), data.cols, data.rows, data.cols*data.channels(), QImage::Format_Grayscale8);
}
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
Img.save(&buffer,"JPG");
return ba;
}
注意这里的Img.save函数,使用jpg的方式来保存图片,这个函数传入的Mat可以是单通道也可以是三通道的没有写四通道rgba的功能。
然后构造函数里面初始化一下client对象
client = new QTcpSocket();
client->connectToHost(QHostAddress("192.168.1.145"),30000);
读一张图片就调用一次write函数,然后再flush()一下,就可以连续发送图片了
client->write(mat_to_QBytearray(buffer));
client->flush();
接下来是客户端
还是先python吧
为什么是先python,因为python可以很方便做一些深度学习的运算,比如识别个人脸这种,所以就先python吧
import threading
import tensorflow as tf
import socket
import numpy as np
import cv2
import time
num_thread = 3
num_thread = 3
all_path_name = []
for i in range(num_thread):
all_path_name.append("")
def func(coord,id):
count = 0
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("192.168.1.145", 40000 + id))
s.listen(5)
sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True))
saver = tf.train.import_meta_graph("D:/all_model/model_1_jingjian/model.ckpt.meta")
saver.restore(sess, "D:/all_model/model_1_jingjian/model.ckpt")
inputs = tf.get_default_graph().get_tensor_by_name('inputs:0')
classes = tf.get_default_graph().get_tensor_by_name('classes:0')
first_image = cv2.imread("D:/128all/image0_2.jpg", cv2.IMREAD_GRAYSCALE)
first_image = cv2.resize(first_image, (128, 128))
first_image_np = np.zeros((1, 128, 128, 1))
first_image_np[0, :, :, 0] = first_image
ojbk = sess.run(classes, feed_dict={inputs: first_image_np})
while not coord.should_stop():
conn, addr = s.accept()
while True:
start = time.clock()
filename = str(count)+".jpg"
count = count + 1
path = "E:/ppp/" + filename
f = open(path, 'ab+')
data = conn.recv(90000)
if not data:
break
f.write(data)
f.close()
image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image, (128, 128))
image_np = np.zeros((1, 128, 128, 1))
image_np[0, :, :, 0] = image
predicted_label = sess.run(classes, feed_dict={inputs: image_np})
end = time.clock()
print(str(predicted_label) + " " + str(end-start))
coord = tf.train.Coordinator()
threads = [threading.Thread(target=func, args=(coord, i)) for i in range(num_thread)]
for t in threads:
t.start()
coord.join(threads)
相当于开三个线程,监听三个端口,然后接受图片保存到一个目录下,然后再用tensorflow去识别这个图片属于哪一类。这里传的都是灰度图。
然后是qt端接受,qt没有识别的功能,看起来舒服很多
首先是引入头文件
#include <QTcpServer>
#include <QTcpSocket>
#include <QtNetwork>
然后是定义类
QTcpServer *server;
QTcpSocket *clientConnection;
然后是初始化
server = new QTcpServer();
server->listen(QHostAddress("192.168.1.145"),40000);
connect(server,SIGNAL(newConnection()),this,SLOT(acceptConnection()));
然后是槽函数
void MainWindow::acceptConnection()
{
clientConnection = server->nextPendingConnection();
connect(clientConnection,SIGNAL(readyRead()),this,SLOT(readClient()));
}
void MainWindow::readClient()
{
QByteArray data;
while (clientConnection->waitForReadyRead(50)) {
data.append((QByteArray)clientConnection->readAll());
}
QBuffer buffer(&data);
buffer.open(QIODevice::ReadOnly);
QImageReader reader(&buffer,"PNG");
QImage img = reader.read();
qDebug() << "got one";
//ui->kkkkk->setPixmap(QPixmap::fromImage(img));
QString save_path = "E:\\ppp\\" + QString::number(count)+".jpg";
img.save(save_path);
count++;
}
这样qt就实现了连续接受图片的功能,顶一个类的属性count用来记录图片的名称,按照count对图片机型命名。