keras模型转化为tensorflow文件并使用VS2010调用

 

keras的h5模型

模型相关

模型测试

h5topb.py

在VS2010中调用


心心念念的深度学习来检测线路问题,终于有个突破性的进展,在此记录下已经做出来的相关工作

keras的h5模型

前期的各种标签制作,训练的苦就不多说了。。。主要针对跟题目相关的部分进行吧

模型相关

一些模型基础设定:

from keras import backend as K
from keras.models import load_model
from keras.preprocessing import image
from keras.optimizers import Adam
from imageio import imread
import numpy as np
from matplotlib import pyplot as plt
import cv2
import time
import os

from models.keras_ssd7 import build_model
from keras_loss_function.keras_ssd_loss import SSDLoss
from keras_layers.keras_layer_AnchorBoxes import AnchorBoxes
from keras_layers.keras_layer_DecodeDetections import DecodeDetections
from keras_layers.keras_layer_DecodeDetectionsFast import DecodeDetectionsFast
from keras_layers.keras_layer_L2Normalization import L2Normalization

from ssd_encoder_decoder.ssd_output_decoder import decode_detections, decode_detections_fast

from data_generator.object_detection_2d_data_generator import DataGenerator
from data_generator.object_detection_2d_photometric_ops import ConvertTo3Channels
from data_generator.object_detection_2d_geometric_ops import Resize
from data_generator.object_detection_2d_misc_utils import apply_inverse_transforms


classes = ['background',
           'open', 'short', 'mousebite', 'spur',
           'copper', 'pin-hole']

# Set the image size.
img_height = 640
img_width = 640
img_channels = 1
n_classes = 6
confidence_threshold = 0.9
target_class = None
batch_size = 4  # batch size when testing

# 1: Build the Keras model

K.clear_session()  # Clear previous models from memory.

model = build_model(image_size=(img_height, img_width, img_channels),
                    n_classes=n_classes,
                    mode='inference',
                    l2_regularization=0.0005,
                    scales=[0.04, 0.08, 0.12, 0.24],
                    aspect_ratios_global=[0.5, 1.0, 2.0],
                    aspect_ratios_per_layer=None,
                    two_boxes_for_ar1=True,
                    steps=None,
                    offsets=None,
                    clip_boxes=False,
                    variances=[1.0, 1.0, 1.0, 1.0],
                    normalize_coords=True,
                    subtract_mean=127.5,
                    divide_by_stddev=127.5,
                    top_k=200)

# 2: Load the trained weights into the model.

# TODO: Set the path of the trained weights.
weights_path = '.h5'

model.load_weights(weights_path, by_name=True)

# 3: Compile the model so that Keras won't complain the next time you load it.

adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)

ssd_loss = SSDLoss(neg_pos_ratio=3, alpha=1.0)

model.compile(optimizer=adam, loss=ssd_loss.compute_loss)   #keras优化器

再对测试图片txt文件进行split并针对batch进行相关设定后只需要把输入也即是图片的维度进行拓展,我这把图片拓展为(batchsize*640*640*1)

模型测试

y_pred = model.predict([X_test_batch, X_temp_batch])

	y_pred_thresh = [y_pred[k][y_pred[k, :, 1] > confidence_threshold] for k in range(y_pred.shape[0])]                 #找到置信度大于0.9的故障预测结果置信度位置

	for pred_idx, box in enumerate(y_pred_thresh):                                                                      #每循环一次为一张图
		nms_out = non_max_suppression_fast_with_index(box[:, -4:], box[:, 1], overlap_thresh=0.05, max_boxes=1000)      #返回故障位置、置信度、计数
		if len(nms_out) < 3:
			y_pred_thresh[pred_idx] = []
		else:
			_, _, new_idx = nms_out
			y_pred_thresh[pred_idx] = box[new_idx, :]                                                                   #缺陷种类、置信度、方位
	print('ellapse time:', time.time() - st)

	# visualize and save results
	for bc_id in range(batch_size):
		result_txt = open(os.path.join(result_path, "res_{}.txt".format(cnt)), 'w')

		for box in y_pred_thresh[bc_id]:
			(x1, y1, x2, y2) = box[-4:]                                                                                 #方位
			tag = int(box[0])                                                                                           #缺陷类型
			score = box[1]                                                                                              #置信度
			if target_class is None or classes[tag] == target_class:
				result_txt.write(
					"{},{},{},{},{},{},{},{},{},{}\n".format(int(x1), int(y1), int(x2), int(y1), int(x2), int(y2),
					                                         int(x1), int(y2), score, classes[tag]))

		result_txt.close()
		gt_dets = []
		img_scaled = cv2.cvtColor(imgs[bc_id], cv2.COLOR_GRAY2BGR)

		for box in y_pred_thresh[bc_id]:                                                                                #缺陷画框
			color = (0, 255, 0)
			x1, y1, x2, y2 = box[-4:].astype(np.int32)
			cv2.rectangle(img_scaled, (x1, y1), (x2, y2), color, 2)                                                     #缺陷矩形框
			# draw the detected proposals
			textLabel = '{}: {:.2f}'.format(classes[int(box[0])], box[1])
			(retval, baseLine) = cv2.getTextSize(textLabel, cv2.FONT_HERSHEY_COMPLEX, 0.5, 1)
			textOrg = (x1, y1 - 2)

			#标记矩形框及文字
			cv2.rectangle(img_scaled, (textOrg[0] - 5, textOrg[1] + baseLine - 5),
			              (textOrg[0] + retval[0] + 5, textOrg[1] - retval[1] - 5), (0, 0, 0), 2)
			cv2.rectangle(img_scaled, (textOrg[0] - 5, textOrg[1] + baseLine - 5),
			              (textOrg[0] + retval[0] + 5, textOrg[1] - retval[1] - 5), (255, 255, 255), -1)
			cv2.putText(img_scaled, textLabel, textOrg, cv2.FONT_HERSHEY_DUPLEX, 0.5, (0, 0, 0), 1)

 得到的测试结果,相比于传统方法确实好了很多~但是!!!!这东西跟项目组的VS2010完全不搭,老大说的时候心态很炸,于是赶紧找到有什么方法能跟VS进行对接。

想法是通过将模型转化成tensorflow模型再利用C++进行调用或者怎么样处理都行

h5topb.py

from keras.models import load_model
import tensorflow as tf
import os
import os.path as osp
#from keras import backend as K
import keras.backend as K
from keras.optimizers import Adam
import h5py

from models.keras_ssd7 import build_model
from keras_loss_function.keras_ssd_loss import SSDLoss
from keras_layers.keras_layer_AnchorBoxes import AnchorBoxes
from keras_layers.keras_layer_DecodeDetections import DecodeDetections
from keras_layers.keras_layer_DecodeDetectionsFast import DecodeDetectionsFast
from keras_layers.keras_layer_L2Normalization import L2Normalization

from ssd_encoder_decoder.ssd_output_decoder import decode_detections, decode_detections_fast

from data_generator.object_detection_2d_data_generator import DataGenerator
from data_generator.object_detection_2d_photometric_ops import ConvertTo3Channels
from data_generator.object_detection_2d_geometric_ops import Resize
from data_generator.object_detection_2d_misc_utils import apply_inverse_transforms


# Set the image size.
img_height = 640
img_width = 640
img_channels = 1
n_classes = 6
confidence_threshold = 0.9
target_class = None
batch_size = 4  # batch size when testing

# 1: Build the Keras model

K.clear_session()  # Clear previous models from memory.销毁当前tf图层

model = build_model(image_size=(img_height, img_width, img_channels),
                    n_classes=n_classes,
                    mode='inference',
                    l2_regularization=0.0005,
                    scales=[0.04, 0.08, 0.12, 0.24],
                    aspect_ratios_global=[0.5, 1.0, 2.0],
                    aspect_ratios_per_layer=None,
                    two_boxes_for_ar1=True,
                    steps=None,
                    offsets=None,
                    clip_boxes=False,
                    variances=[1.0, 1.0, 1.0, 1.0],
                    normalize_coords=True,
                    subtract_mean=127.5,
                    divide_by_stddev=127.5,
                    top_k=200)

# 2: Load the trained weights into the model.

# TODO: Set the path of the trained weights.
weights_path = ''

model.load_weights(weights_path, by_name=True)

# 3: Compile the model so that Keras won't complain the next time you load it.

adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)

ssd_loss = SSDLoss(neg_pos_ratio=3, alpha=1.0)

model.compile(optimizer=adam, loss=ssd_loss.compute_loss)   #keras优化器
#model.save('test.h5')
#del model

#路径参数
input_path = 'E:/python/'
weight_file = '.h5'
weight_file_path = osp.join(input_path,weight_file)
output_graph_name = weight_file[:-3] + '.pb'
#转换函数
def h5_to_pb(h5_model,output_dir,model_name,out_prefix = "output_",log_tensorboard = True):
    if osp.exists(output_dir) == False:
        os.mkdir(output_dir)
    out_nodes = []
    for i in range(len(h5_model.outputs)):
        out_nodes.append(out_prefix + str(i + 1))
        tf.identity(h5_model.output[i],out_prefix + str(i + 1))
    sess = K.get_session()
    from tensorflow.python.framework import graph_util,graph_io
    init_graph = sess.graph.as_graph_def()
    main_graph = graph_util.convert_variables_to_constants(sess,init_graph,out_nodes)
    graph_io.write_graph(main_graph,output_dir,name = model_name,as_text = False)
    if log_tensorboard:
        from tensorflow.python.tools import import_pb_to_tensorboard
        import_pb_to_tensorboard.import_to_tensorboard(osp.join(output_dir,model_name),output_dir)
#输出路径
output_dir = osp.join(os.getcwd(),"trans_model")
#加载模型

#from keras  import losses
#h5_model = load_model(weight_file_path,custom_objects={'AnchorBoxes':AnchorBoxes,'DecodeDetections':DecodeDetections,'losses.compute_loss':losses.compute_loss})
h5_to_pb(model,output_dir = output_dir,model_name = output_graph_name)

这里有坑要注意,对于普通的模型基本上输入输出很容易确定,但是复杂点的模型得自己仔细研究确定输入输出的具体东西,不然超级多坑。。。可以用下面这段代码查看模型的结点

import tensorflow as tf
import os

model_dir = ''
model_name = ''



def create_graph():
	with tf.gfile.FastGFile(os.path.join(
			model_dir, model_name), 'rb') as f:
		graph_def = tf.GraphDef()
		graph_def.ParseFromString(f.read())
		tf.import_graph_def(graph_def, name='')


create_graph()
tensor_name_list = [tensor.name for tensor in tf.get_default_graph().as_graph_def().node]
for tensor_name in tensor_name_list:
	print(tensor_name, '\n')

在深入了解了keras和tensorflow对于模型的调用的不同,再结合参考了object detection API的调用模型代码,写出了对单张图片的测试并能画出矩形框。

# Import packages
import os
import cv2
import numpy as np
import tensorflow as tf
import sys

# This is needed since the notebook is stored in the object_detection folder.
sys.path.append("..")

# Import utilites
from utils import label_map_util
from utils import visualization_utils as vis_util

。
。
。
NUM_CLASSES = 6

# Load the label map.
# Label maps map indices to category names, so that when our convolution
# network predicts `5`, we know that this corresponds to `king`.
# Here we use internal utility functions, but anything that returns a
# dictionary mapping integers to appropriate string labels would be fine
label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
category_index = label_map_util.create_category_index(categories)

# Load the Tensorflow model into memory.
detection_graph = tf.Graph()
with detection_graph.as_default():
    od_graph_def = tf.GraphDef()
    with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
        serialized_graph = fid.read()
        od_graph_def.ParseFromString(serialized_graph)
        tf.import_graph_def(od_graph_def, name='')

    sess = tf.Session(graph=detection_graph)

imagetest_tensor = detection_graph.get_tensor_by_name('input_test:0')
imagetemp_tensor = detection_graph.get_tensor_by_name('input_temp:0')
output_1 = detection_graph.get_tensor_by_name('output_1:0')

。
。
。


# Perform the actual detection by running the model with the image as input(0:classes;1:score;2:xmin;3:ymin;4:xmax;5:ymax)
(output) = sess.run(
    [output_1],
    feed_dict={imagetest_tensor: X_test,imagetemp_tensor: X_temp})

# Draw the results of the detection (aka 'visulaize the results')
boxes = output[0][0:200][:,-4:]
boxes = boxes[:,[1,0,3,2]]          #自带画矩形框函数列相关不一样,得调整
classes = output[0][0:200][:,0]
score = output[0][0:200][:,1]

vis_util.visualize_boxes_and_labels_on_image_array(
    img,
    np.squeeze(boxes),
    np.squeeze(classes).astype(np.int32),
    np.squeeze(score),
    category_index,
    use_normalized_coordinates=False,
    line_thickness=4,
    min_score_thresh=0.90)

# All the results have been drawn on image. Now display the image.
cv2.imshow('Object detector', img)
cv2.imwrite(PATH_TO_IMAGERESULT,img)

在VS2010中调用

#include<iostream>
#include <Python.h>
#include<windows.h>
using namespace std;
void testImage(char * path) //执行函数
{
	try{
		Py_Initialize();         
		PyEval_InitThreads();
		PyObject*pFunc = NULL;
		PyObject*pArg = NULL;
		PyObject* module = NULL;
		
		PyRun_SimpleString("import sys");
		PyRun_SimpleString("sys.path.append(r'D:\sxl\VisualStudio\CallTensorFlow2\x64\Debug\')");
		
		
		module = PyImport_ImportModule("Load_OCR_pb");//myModel:Python文件名  
		if (!module) {
			printf("cannot open module!");
			Py_Finalize();
			return;
		}
		pFunc = PyObject_GetAttrString(module, "test_one_image");//test_one_image:Python文件中的函数名,这里的"test_one_image",一定要和读取pb模型的Load_OCR_pb.py里面的函数名称一致,重要!
		if (!pFunc) {
			printf("cannot open FUNC!");
			Py_Finalize();
			return;
		}
		//开始调用model  
		pArg = Py_BuildValue("(s)", path); 
		if (module != NULL) {
			PyGILState_STATE gstate;
			gstate = PyGILState_Ensure();
			PyEval_CallObject(pFunc, pArg);
			PyGILState_Release(gstate);
		}
	}
	catch (exception& e)
	{
		cout << "Standard exception: " << e.what() << endl;
	}
}


int main()
{
	char * path = "D:\\1.jpg"; //图片路径
	testImage(path); //调用函数
	system("pause");
	return 0;
}

参考:https://blog.csdn.net/xiaomu_347/article/details/81040855

https://blog.csdn.net/sxlsxl119/article/details/81937815

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值