做网站工作的怎么填职务,小程序价格表一览表,专业的深圳电商app开发,官方网站手机 优帮云本项目旨在利用计算机视觉技术和深度学习算法#xff0c;实现对停车场车位状态的实时自动识别。通过摄像头监控停车场内部#xff0c;系统能够高效准确地辨认车位是否被占用#xff0c;为车主提供实时的空闲车位信息#xff0c;同时为停车场管理者提供智能化的车位管理工具…本项目旨在利用计算机视觉技术和深度学习算法实现对停车场车位状态的实时自动识别。通过摄像头监控停车场内部系统能够高效准确地辨认车位是否被占用为车主提供实时的空闲车位信息同时为停车场管理者提供智能化的车位管理工具。该系统结合了OpenCV的强大图像处理能力与Keras的易用性便于快速构建和部署。 技术栈
OpenCV用于图像的预处理包括视频捕获、图像处理如灰度转换、滤波、边缘检测等以及ROI感兴趣区域的选取为深度学习模型提供高质量的输入。Keras基于TensorFlow的高级API用于搭建和训练深度学习模型。项目中可能采用预训练模型如VGGNet、ResNet等进行迁移学习通过微调模型来适应车位识别任务或者从零开始构建卷积神经网络CNN模型进行车位状态分类。
项目流程 数据收集与预处理首先通过摄像头录制停车场视频从中截取包含车位的画面人工标注车位状态如空闲或占用。接着对图像进行归一化、增强等预处理创建训练和验证数据集。 模型训练使用Keras构建深度学习模型加载预处理后的数据集进行训练。训练过程中可能涉及调整超参数、优化器选择、损失函数配置等以达到理想的分类性能。 模型验证与优化在验证集上评估模型性能根据准确率、召回率等指标调整模型结构或参数进行模型优化。 实时检测与应用将训练好的模型集成到OpenCV中实现实时视频流处理。系统不断捕获停车场的视频帧进行图像处理后通过模型预测车位状态。识别结果以可视化方式展示如在视频流中标记车位为空闲或占用并可进一步集成到停车场管理系统实现车位引导、计费等功能。
特色与优势
实时性系统能够实时监控车位状态及时更新信息提高停车场的运营效率。准确性深度学习模型具有强大的特征学习能力即使在复杂光照、遮挡等条件下也能保持较高识别准确率。易部署与扩展基于OpenCV和Keras的方案易于开发和调试且模型可根据新数据持续优化便于后续维护和功能升级。智能化管理为停车场管理者提供精准的车位占用情况有助于优化停车资源分配提升用户体验。
总结 此项目通过融合OpenCV的图像处理能力和Keras构建的深度学习模型实现了对停车场车位状态的自动识别是智能交通系统和智慧城市应用中的一个重要组成部分具有广泛的应用前景和社会价值。
from __future__ import division # 改变 Python 2 中除法操作符 / 的默认行为使其表现得像 Python 3 中的除法操作符,结果会保留小数部分
import matplotlib.pyplot as plt # 用于创建图表和可视化数据的 Python 库
import cv2
import os, glob # glob文件名匹配的模块
import numpy as np
from PIL import Image
from keras.applications.imagenet_utils import preprocess_input
from keras.models import load_model
from keras.preprocessing import image
from Parking import Parking
import pickle # 序列化和反序列化对象的标准模块cwd os.getcwd() # 获取当前工作目录def img_process(test_images, park):# 过滤背景低于lower_red和高于upper_red的部分分别编程0lower_red~upper_red之间的值编程255# map 函数用于将一个函数应用到可迭代对象的每个元素并返回结果# 通过 list 函数将其转换为列表white_yellow_images list(map(park.select_rgb_white_yellow,test_images))park.show_images(white_yellow_images)# 转灰度图gray_images list(map(park.convert_gray_scale, white_yellow_images))park.show_images(gray_images)# 进行边缘检测edge_images list(map(lambda image: park.detect_edges(image),gray_images))park.show_images(edge_images)# 根据需要设定屏蔽区域roi_images list(map(park.select_region, edge_images))park.show_images(roi_images)# 霍夫变换得出直线list_of_lines list(map(park.hough_line, roi_images))# zip 函数来同时迭代 test_images 和 list_of_lines 中的元素line_images []for image,lines in zip(test_images,list_of_lines):line_images.append(park.draw_lines(image,lines))park.show_images(line_images)rect_images []rect_coords [] # 列矩形for image,lines in zip(test_images, list_of_lines):# 过滤部分直线对直线进行排序得出每一列的起始点和终止点并将列矩形画出来new_image,rects park.identify_blocks(image,lines)rect_images.append(new_image)rect_coords.append(rects)park.show_images(rect_images)delineated []spot_pos []for image,rects in zip(test_images, rect_coords):# 在图上将停车位画出来并返回字典{坐标车位序号}new_image,spot_dict park.draw_parking(image,rects)delineated.append(new_image)spot_pos.append(spot_dict)park.show_images(delineated)final_spot_dict spot_pos[1]print(len(final_spot_dict))with open(spot_dict.pickle,wb) as handle:pickle.dump(final_spot_dict,handle,propertypickle.HIGHEST_PROTOCOL)park.save_images_for_cnn(test_images[0],final_spot_dict)return final_spot_dictdef keras_model(weights_path):model load_model(weights_path)return modeldef img_test(test_image,final_spot_dict,model,class_dictionary):for i in range (len(test_images)):predicted_images park.predict_on_image(test_images[i],final_spot_dict,model,class_dictionary)def video_test(video_name,final_spot_dict,model,class_dictionary):name video_namecap cv2.VideoCapture(name)park.predict_on_video(name,final_spot_dict,model,class_dictionary,retTrue)if __name__ __main__:test_images [plt.imread(path) for path in glob.glob(test_images/*.jpg)]weights_path car1.h5video_name parking_video.mp4class_dictionary {}class_dictionary[0] emptyclass_dictionary[1] occupiedpark Parking()park.show_image(test_images)final_spot_dict img_process(test_images, park)model keras_model(weights_path)img_test(test_images,final_spot_dict,model,class_dictionary)video_test(video_name,final_spot_dict,model,class_dictionary)parking py
import matplotlib.pyplot as plt
import cv2
import os,glob
import numpy as npclass Parking:def show_images(self, images, cmapNone):cols 2rows (len(images) 1)//cols # //为整除运算符plt.figure(figsize(15,12)) # 创建一个图形窗口并指定其大小为 15x12 英寸for i,image in enumerate(images):plt.subplot(rows, cols, i1) # 在当前图形窗口中创建一个子图,i1 是因为子图的编号是从 1 开始的# 检查图像的维度如果图像是二维的灰度图像则将颜色映射设置为灰度否则保持传入的 cmap 参数不变cmap gray if len(image.shape)2 else cmapplt.imshow(image, cmapcmap)plt.xticks([]) # 去除 x 轴和 y 轴的刻度标签plt.yticks([])plt.tight_layout(pad0,h_pad0,w_pad0) # 调整子图之间的间距plt.show()def cv_show(self, name, img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()def select_rgb_white_yellow(self,image):# 过滤掉背景lower np.uint8([120,120,120])upper np.uint8([255,255,255])# 低于lower_red和高于upper_red的部分分别编程0lower_red~upper_red之间的值编程255相当于过滤背景white_mask cv2.inRange(image,lower,upper)self.cv_show(white_mask,white_mask)# 与操作masked cv2.bitwise_and(image, image, maskwhite_mask)self.cv_show(masked,masked)return maskeddef convert_gray_scale(selfself,image):return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 提取图像中的边缘信息# 返回的是一个二值图像其中边缘点被标记为白色255而非边缘点被标记为黑色0def detect_edges(self, image, low_threshole50, high_threshold200):return cv2.Canny(image, low_threshole, high_threshold)def filter_region(self, image, vertices):# 剔除掉不需要的地方mask np.zeros_like(image) # 创建和原图一样大的图置零if len(mask.shape)2: # 是否为一张灰度图cv2.fillPoly(mask, vertices, 255) # 使用顶点vertices在mask上填充多边形并置为255白色self.cv_show(mask,mask)return cv2.bitwise_and(image,mask)def select_region(self, image):# 手动选择区域# 首先通过顶点定义多边形。rows, cols image.shape[:2] # h和wpt_1 [cols*0.05, rows*0.09]pt_2 [cols*0.05, rows*0.70]pt_3 [cols*0.30, rows*0.55]pt_4 [cols*0.6, rows*0.15]pt_5 [cols*0.90, rows*0.15]pt_6 [cols*0.90, rows*0.90]vertices np.array([[pt_1, pt_2, pt_3, pt_4, pt_5, pt_6]],dtypenp.int32)point_img image.copy()point_img cv2.cvtColor(point_img, cv2.COLOR_BGR2GRAY)for point in vertices[0]:cv2.circle(point_img,(point[0], point[1]), 10, (0,0,255), 4)self.cv_show(point_img,point_img)return self.filter_region(image, vertices)# 霍夫变换得出直线def hough_line(self,image):# 检测输入图像中的直线并返回检测到的直线的端点坐标# 输入的图像需要是边缘检测后的结果# minLineLength(线的最短长度比这个短的都被忽略和MaxLineCap两条直线之间的最大间隔小于辞职认为是一条直线# rho以像素为单位的距离分辨率通常设置为 1 像素# thrta角度精度# threshod直线交点数量阈值。只有累加器中某个点的投票数高于此阈值才被认为是一条直线。return cv2.HoughLinesP(image, rho0.1, thrtanp.pi/10, threshold15,minLineLength9,maxLineGap4)# 过滤霍夫变换检测到的直线def draw_lines(self, image, lines, color[255,0,0], thickness2, make_copyTrue):if make_copy:image np.copy(image)cleaned []for line in lines:for x1,y1,x2,y2 in line:if abs(y2-y1) 1 and abs(x2-x1) 25 and abs(x2-x1) 55:cleaned.append((x1,y1,x2,y2))cv2.line(image, (x1,y1), (x2,y2), color, thickness)print( No lines detected: , len(cleaned))return image# 过滤部分直线对直线进行排序得出每一列的起始点和终止点并将列矩形画出来def identify_blocks(self, image, lines, make_copyTrue):if make_copy:new_image np.copy(image)# step1: 过滤部分直线cleaned []for line in lines:for x1,y1,x2,y2 in line:if abs(y2-y1) 1 and abs(x2-x1) 25 and abs(x2-x1) 55:cleaned.append((x1,y1,x2,y2))# step2: 对直线按照 起始点的x和y坐标 进行排序import operator # 可以使用其中的各种函数来进行操作例如比较、算术list1 sorted(cleaned, keyoperator.itemgetter(0,1)) # 从列表的每个元素中获取索引为0和1的值然后将这些值用作排序的依据# step3: 找到多个列相当于每列是一排车clusters {} # 列数对应该列有哪些车位线dIndex 0clus_dist 10for i in range(len(list1) - 1):distance abs(list1[i1][0] - list1[i][0]) # 根据前后两组车位线的x1距离if distance clus_dist:if not dIndex in clusters.keys(): clusters[dIndex] []clusters[dIndex].append(list1[i])clusters[dIndex].append(list1[i 1])else:dIndex 1# step4: 得到每一列的四个坐标rects {} # 每一列的四个角的坐标i 0for key in clusters:all_list clusters[key]# 将列表 all_list 转换为一个集合set去重# {(10, 20, 30, 40), (20, 30, 40, 50)} 转为 [(10, 20, 30, 40), (20, 30, 40, 50)]cleaned list(set(all_list))if len(cleaned) 5:cleaned sorted(cleaned, keylambda tup: tup[1]) # 按y1进行排序avg_y1 cleaned[0][1] # 第一条线段的起始点 y 坐标avg_y2 cleaned[-1][1] # 最后一条线段的起始点 y 坐标即整个区域的上下边界avg_x1 0avg_x2 0for tup in cleaned: # 累加起始点和结束点的 x 坐标avg_x1 tup[0]avg_x2 tup[2]avg_x1 avg_x1/len(cleaned) # 取平均起始点和结束点x坐标值avg_x2 avg_x2/len(cleaned)rects[i] (avg_x1, avg_y1,avg_x2,avg_y2)i 1print(Num Parking Lanes:, len(rects))# step5: 把列矩形画出来buff 7for key in rects:tup_topLeft (int(rects[key][0] - buff), int(rects[key][1])) # x1-buff, y1tup_botRight (int(rects[key][2] buff), int(rects[key][3])) # x2buff, y2cv2.rectangle(new_image, tup_topLeft, tup_botRight,(0,255,0),3)return new_image,rects# 在图上将停车位画出来并返回字典{坐标车位序号}def draw_parking(self, image, rects, make_copyTrue, color[255,0,0], thickness2, saveTrue):if make_copy:new_image np.copy(image)gap 15.5 # 一个车位大致高度spot_dict {} # 字典一个车位对应一个位置tot_spots 0 # 总车位# 微调adj_y1 {0: 20, 1: -10, 2: 0, 3: -11, 4: 28, 5: 5, 6: -15, 7: -15, 8: -10, 9: -30, 10: 9, 11: -32}adj_y2 {0: 30, 1: 50, 2: 15, 3: 10, 4: -15, 5: 15, 6: 15, 7: -20, 8: 15, 9: 15, 10: 0, 11: 30}adj_x1 {0: -8, 1: -15, 2: -15, 3: -15, 4: -15, 5: -15, 6: -15, 7: -15, 8: -10, 9: -10, 10: -10, 11: 0}adj_x2 {0: 0, 1: 15, 2: 15, 3: 15, 4: 15, 5: 15, 6: 15, 7: 15, 8: 10, 9: 10, 10: 10, 11: 0}for key in rects:tup rects[key]x1 int(tup[0] adj_x1[key])x2 int(tup[2] adj_x2[key])y1 int(tup[1] adj_y1[key])y2 int(tup[3] adj_y2[key])cv2.rectangle(new_image,(x1,y1), (x2,y2), (0,255,0), 2)num_splits int(abs(y2-y1)//gap) # 一列总共有多少个车位for i in range (0,num_splits1): # 画车位框y int(y1 i*gap)cv2.rectangle(new_image, (x1,y), (x2,y2), (0,255,0), 2)if key 0 and key len(rects)-1:# 竖直线x int((x1x2)/2)cv2.line(new_image,(x,y1),(x,y2),color,thickness)# 计算数量if key 0 or key (len(rects) - 1): # 对于第一列和最后一列只有一排车位tot_spots num_splits 1else:tot_spots 2*(num_splits 1) # 一列有两排车位# 字典对应好if key 0 or key (len(rects) - 1): # 对于第一列和最后一列只有一排车位for i in range(0, num_splits1):cur_len len(spot_dict)y int(y1 i*gap)spot_dict[(x1,y,x2,ygap)] cur_len 1else:for i in range(0, num_splits1):cur_len len(spot_dict)y int(y1 i*gap)x int((x1x2)/2)spot_dict[(x1,y,x,ygap)] cur_len 1spot_dict[(x,y,x2,ygap)] cur_len 2print(total parking spaces: , tot_spots, cur_len)if save:filename with_parking.jpgcv2.imwrite(filename, new_image)return new_image, spot_dict# 根据传入的起始点和终止点坐标列表画框def assign_spots_map(self, image, spot_dict, make_copy True, color[255,0,0], thickness2):if make_copy:new_image np.copy(image)for spot in spot_dict.keys():(x1,y1,x2,y2) spotcv2.rectangle(new_image,(int(x1),int(y1)), (int(x2),int(y2)), color, thickness)return new_image# 遍历字典{坐标车位号}在图片中截取对应坐标的图像按车位号保存下来def save_images_for_cnn(self, image, spot_dict, folder_name cnn_data):for spot in spot_dict.keys():(x1,y1,x2,y2) spot(x1,y1,x2,y2) (int(x1),int(y1),int(x2),int(y2))# 裁剪spot_img image[y1:y2, x1:x2]spot_img cv2.resize(spot_img, (0,0), fx2.0, fy2.0)spot_id spot_dict[spot]filename spot str(spot_id) .jpgprint(spot_img.shape, filename, (x1,x2,y1,y2))cv2.imwrite(os.path.join(folder_name, filename), spot_img)# 将图像进行归一化并将其转换成一个符合深度学习模型输入要求的四维张量进行训练def make_prediction(self, image, model, class_dictionary):# 预处理img image/255. # 将图像的像素值归一化到 [0, 1] 的范围内# 将图像转换成一个四维张量image np.expend_dims(img, axis 0)# 将图片调用keras算法进行预测class_predicted model.predict(image) # 得出预测结果inID np.argmax(class_predicted[0]) # 找到数组中最大值所在的索引label class_dictionary[inID]return labeldef predict_on_image(self, image, spot_dict, model, class_dictionary,make_copyTrue, color[0,255,0], alpha0.5):if make_copy:new_image np.copy(image)overlay np.copy(image)self.cv_show(new_image,new_image)cnt_empty 0all_spots 0for spot in spot_dict.keys():all_spots 1(x1, y1, x2, y2) spot(x1, y1, x2, y2) (int(x1), int(y1), int(x2), int(y2))spot_img image[y1:y2, x1:x2]spot_img cv2.resize(spot_img, (48,48))label self.make_prediction(spot_img, model, class_dictionary)if label empty:cv2.rectangle(overlay, (int(x1), int(y1)), (int(x2), int(y2)), color, -1)cnt_empty 1cv2.addWeighted(overlay, alpha, new_image, 1-alpha, 0, new_image)cv2.putText(new_image, Available: %d spots %cnt_empty, (30,95),cv2.FONT_HERSHEY_SIMPLEX,0.7,(255,255,255),2)cv2.putText(new_image, Total: %d spots %all_spots, (30,125),cv2.FONT_HERSHEY_SIMPLEX, 0.7,(255,255,255),2)save Falseif save:filename with_parking.jpgcv2.imwrite(filename, new_image)self.cv_show(new_image,new_image)return new_imagedef predict_on_video(self, video_name, final_spot_dict, model, class_dictionary, retTrue):cap cv2.VideoCapture(video_name)count 0while ret:ret, image cap.read()count 1if count 5:count 0new_image np.copy(image)overlay np.copy(image)cnt_empty 0all_spots 0color [0,255,0]alpha 0.5for spot in final_spot_dict.keys():all_spots 1(x1,y1,x2,y2) spot(x1,y1,x2,y2) (int(x1), int(y1), int(x2), int(y2))spot_img image[y1:y2, x1:x2]spot_img cv2.resize(spot_img, (48,48))label self.make_prediction(spot_img, model, class_dictionary)if label empty:cv2.rectangle(overlay, (int(x1),int(y1)), (int(x2),int(y2)), color, -1)cnt_empty 1cv2.addWeighted(overlay, alpha, new_image, 1-alpha, 0, new_image)cv2.putText(new_image,Available: %d spots % cnt_empty,(30,95),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255),2)cv2.putText(new_image, Total: %d spots %all_spots, (30,125),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 2)cv2.imshow(frame,new_image)# 检测用户是否按下了 q 键if cv2.waitKey(10) 0xFF ord(q): # 通过 0xFF 操作可以确保只获取ASCII码的最后一个字节breakcv2.destroyWindow()cap.release()
文章转载自: http://www.morning.prprz.cn.gov.cn.prprz.cn http://www.morning.mcmpq.cn.gov.cn.mcmpq.cn http://www.morning.rfbt.cn.gov.cn.rfbt.cn http://www.morning.rfpxq.cn.gov.cn.rfpxq.cn http://www.morning.sgrdp.cn.gov.cn.sgrdp.cn http://www.morning.fflnw.cn.gov.cn.fflnw.cn http://www.morning.wfyqn.cn.gov.cn.wfyqn.cn http://www.morning.nzcys.cn.gov.cn.nzcys.cn http://www.morning.jrksk.cn.gov.cn.jrksk.cn http://www.morning.addai.cn.gov.cn.addai.cn http://www.morning.tgtrk.cn.gov.cn.tgtrk.cn http://www.morning.bmhc.cn.gov.cn.bmhc.cn http://www.morning.nsrlb.cn.gov.cn.nsrlb.cn http://www.morning.brhxd.cn.gov.cn.brhxd.cn http://www.morning.gmmxh.cn.gov.cn.gmmxh.cn http://www.morning.gczzm.cn.gov.cn.gczzm.cn http://www.morning.bdwqy.cn.gov.cn.bdwqy.cn http://www.morning.rnjgh.cn.gov.cn.rnjgh.cn http://www.morning.thmlt.cn.gov.cn.thmlt.cn http://www.morning.lwnb.cn.gov.cn.lwnb.cn http://www.morning.pdgqf.cn.gov.cn.pdgqf.cn http://www.morning.kyctc.cn.gov.cn.kyctc.cn http://www.morning.gklxm.cn.gov.cn.gklxm.cn http://www.morning.wnbqy.cn.gov.cn.wnbqy.cn http://www.morning.ntyanze.com.gov.cn.ntyanze.com http://www.morning.nhpgm.cn.gov.cn.nhpgm.cn http://www.morning.supera.com.cn.gov.cn.supera.com.cn http://www.morning.qxlyf.cn.gov.cn.qxlyf.cn http://www.morning.bkqw.cn.gov.cn.bkqw.cn http://www.morning.cbndj.cn.gov.cn.cbndj.cn http://www.morning.gxtfk.cn.gov.cn.gxtfk.cn http://www.morning.nthyjf.com.gov.cn.nthyjf.com http://www.morning.rpgdd.cn.gov.cn.rpgdd.cn http://www.morning.hsdhr.cn.gov.cn.hsdhr.cn http://www.morning.pycpt.cn.gov.cn.pycpt.cn http://www.morning.syssdz.cn.gov.cn.syssdz.cn http://www.morning.dnjwm.cn.gov.cn.dnjwm.cn http://www.morning.qggcc.cn.gov.cn.qggcc.cn http://www.morning.yrck.cn.gov.cn.yrck.cn http://www.morning.pypbz.cn.gov.cn.pypbz.cn http://www.morning.wngpq.cn.gov.cn.wngpq.cn http://www.morning.xjkr.cn.gov.cn.xjkr.cn http://www.morning.rbsxf.cn.gov.cn.rbsxf.cn http://www.morning.hnkkf.cn.gov.cn.hnkkf.cn http://www.morning.bqwrn.cn.gov.cn.bqwrn.cn http://www.morning.qgxnw.cn.gov.cn.qgxnw.cn http://www.morning.mrcpy.cn.gov.cn.mrcpy.cn http://www.morning.pnmtk.cn.gov.cn.pnmtk.cn http://www.morning.wmglg.cn.gov.cn.wmglg.cn http://www.morning.fjgwg.cn.gov.cn.fjgwg.cn http://www.morning.drcnn.cn.gov.cn.drcnn.cn http://www.morning.tkgjl.cn.gov.cn.tkgjl.cn http://www.morning.yrnyz.cn.gov.cn.yrnyz.cn http://www.morning.jwxnr.cn.gov.cn.jwxnr.cn http://www.morning.ckbmz.cn.gov.cn.ckbmz.cn http://www.morning.rqbkc.cn.gov.cn.rqbkc.cn http://www.morning.tgts.cn.gov.cn.tgts.cn http://www.morning.wgrl.cn.gov.cn.wgrl.cn http://www.morning.qwfl.cn.gov.cn.qwfl.cn http://www.morning.cgtrz.cn.gov.cn.cgtrz.cn http://www.morning.wwwghs.com.gov.cn.wwwghs.com http://www.morning.mngh.cn.gov.cn.mngh.cn http://www.morning.knscf.cn.gov.cn.knscf.cn http://www.morning.glncb.cn.gov.cn.glncb.cn http://www.morning.pxrfm.cn.gov.cn.pxrfm.cn http://www.morning.nhzzn.cn.gov.cn.nhzzn.cn http://www.morning.xlclj.cn.gov.cn.xlclj.cn http://www.morning.egmux.cn.gov.cn.egmux.cn http://www.morning.wdxr.cn.gov.cn.wdxr.cn http://www.morning.lqpzb.cn.gov.cn.lqpzb.cn http://www.morning.xflzm.cn.gov.cn.xflzm.cn http://www.morning.krwzy.cn.gov.cn.krwzy.cn http://www.morning.fylsz.cn.gov.cn.fylsz.cn http://www.morning.tqlhn.cn.gov.cn.tqlhn.cn http://www.morning.ryfpx.cn.gov.cn.ryfpx.cn http://www.morning.llxyf.cn.gov.cn.llxyf.cn http://www.morning.jpdbj.cn.gov.cn.jpdbj.cn http://www.morning.xnqjs.cn.gov.cn.xnqjs.cn http://www.morning.mdwtm.cn.gov.cn.mdwtm.cn http://www.morning.zrlwl.cn.gov.cn.zrlwl.cn