鱼C论坛

 找回密码
 立即注册
查看: 2029|回复: 14

[已解决]python文件引入同级文件出现错误

[复制链接]
发表于 2020-3-20 11:39:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
attempted relative import with no known parent package
最佳答案
2020-3-20 17:21:36
导入模块时 . 表示导入这个的某一个模块
因为你就这一个代码,不能算是包。
要想变成包,应该在这个代码所在的文件夹中,新建一个 __init__.py 文件。
并且则这个文件夹里得有 lpr.py 这个模块。

或者你可以把 from .lpr import LPRLite as pr 中的 . 去掉,可以没有 __init__.py 文件,
因为 Python 导入模块会现在当前文件夹里寻找有没有模块。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-20 11:42:39 | 显示全部楼层
请先学会提问题
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-20 12:24:21 | 显示全部楼层

刚刚一直没法上传图片...
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-20 13:12:22 | 显示全部楼层
没法上传图片那就把源代码和运行结果发过来呀
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-20 14:53:08 | 显示全部楼层
lixiangyv 发表于 2020-3-20 13:12
没法上传图片那就把源代码和运行结果发过来呀
  1. import cv2
  2. from .lpr import LPRLite as pr
  3. import numpy as np

  4. def recognizeOneImage(src):
  5.     # grr = cv2.imread("image/(2).jpg")
  6.     grr = cv2.imread(src)
  7.     model = pr.LPR("model/cascade.xml", "model/model12.h5", "model/ocr_plate_all_gru.h5")
  8.     for pstr, confidence, rect in model.SimpleRecognizePlateByE2E(grr):
  9.         if confidence > 0.7:
  10.             image = drawRectBox(grr, rect, pstr + " " + str(round(confidence, 3)))
  11.             print("plate_str:")
  12.             print(pstr)
  13.             print("plate_confidence")
  14.             print(confidence)

  15.     cv2.imwrite('images_rec1/' + 'image_new.jpg', image)
  16.     return pstr


  17. str = recognizeOneImage('image/(2).jpg')
  18. print(str)
  19. print("00000000000000000")
复制代码



出现错误
  1. D:\Anaconda\envs\tensorflow\python.exe D:/pycharm/djangocode/projectt/project4/myApp/python_LPR/demo.py
  2. Traceback (most recent call last):
  3.   File "D:/pycharm/djangocode/projectt/project4/myApp/python_LPR/demo.py", line 63, in <module>
  4.     from .lpr import LPRLite as pr
  5. ImportError: attempted relative import with no known parent package
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-20 17:21:36 | 显示全部楼层    本楼为最佳答案   
导入模块时 . 表示导入这个的某一个模块
因为你就这一个代码,不能算是包。
要想变成包,应该在这个代码所在的文件夹中,新建一个 __init__.py 文件。
并且则这个文件夹里得有 lpr.py 这个模块。

或者你可以把 from .lpr import LPRLite as pr 中的 . 去掉,可以没有 __init__.py 文件,
因为 Python 导入模块会现在当前文件夹里寻找有没有模块。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-21 12:23:51 | 显示全部楼层
lixiangyv 发表于 2020-3-20 17:21
导入模块时 . 表示导入这个包的某一个模块,
因为你就这一个代码,不能算是包。
要想变成包,应该在这个 ...

getit!谢谢大佬嘻嘻嘻
那啥..我再问你一个问题呗,看看您会不会
有遇到类似这样的错误嘛
  1.   File "D:\Anaconda\lib\site-packages\h5py\_hl\files.py", line 92, in make_fid
  2.     fid = h5f.open(name, flags, fapl=fapl)
  3.   File "h5py\_objects.pyx", line 54, in h5py._objects.with_phil.wrapper (C:\Minonda\conda-bld\h5py_1482647201869\work\h5py\_ob
  4. jects.c:2866)
  5.   File "h5py\_objects.pyx", line 55, in h5py._objects.with_phil.wrapper (C:\Minonda\conda-bld\h5py_1482647201869\work\h5py\_ob
  6. jects.c:2824)
  7.   File "h5py\h5f.pyx", line 76, in h5py.h5f.open (C:\Minonda\conda-bld\h5py_1482647201869\work\h5py\h5f.c:2112)
  8. OSError: Unable to open file (Unable to open file: name = 'model/model12.h5', errno = 2, error message = 'no such file or dire
  9. ctory', flags = 0, o_flags = 0)
  10. [21/Mar/2020 12:15:57] "POST /upload_
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-29 09:33:11 | 显示全部楼层
愿你 发表于 2020-3-21 12:23
getit!谢谢大佬嘻嘻嘻
那啥..我再问你一个问题呗,看看您会不会
有遇到类似这样的错误嘛

能把源码发过来吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-1 10:17:24 | 显示全部楼层
lixiangyv 发表于 2020-3-29 09:33
能把源码发过来吗

源码用啥发阿 代码格式那样吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-2 10:49:44 | 显示全部楼层
用 <> 这个发
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-2 13:55:50 | 显示全部楼层

首先,我要实现的小程序是从微信小程序端上传一张车牌图片到后端(这里的后端用django搭建),django后台要额外调用另一个python文件(该文件能够识别出车牌),这里的调用使用rpc远程调用。
django后台相关view代码:
  1. def upload_handle(request):
  2.     print("====")
  3.     user=request.POST.get("nickName")
  4.     gender = request.POST.get("gender")
  5.     avatarUrl = request.POST.get("avatarUrl")
  6.     user_obj=UserList.objects.create(user=user,gender=gender,avatarUrl=avatarUrl)
  7.     user_obj.save()

  8.     card_imgs=request.FILES.get('file')
  9.     card_obj = CardList.objects.create(card_img=card_imgs)
  10.     card_obj.save()
  11.     current_dir = os.getcwd()
  12.     path = current_dir + card_obj.card_img.url
  13.     card_obj.card_address = str(path)
  14.     card_obj.save()
  15.     print("111")
  16.     print(path)
  17.     server = ServerProxy("http://localhost:8888") # 初始化服务器
  18.     print(server.get_platestr(path))
  19.     platestr=server.get_platestr(path)
  20.     print("222")

  21.     return HttpResponse(platestr)
复制代码

额外调用的python文件代码:
  1. import cv2
  2. import os
  3. import sys
  4. import numpy as np
  5. import tensorflow as tf

  6. car_plate_w, car_plate_h = 136, 36
  7. char_w, char_h = 20, 20
  8. char_table = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
  9.               'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '川', '鄂', '赣', '甘', '贵',
  10.               '桂', '黑', '沪', '冀', '津', '京', '吉', '辽', '鲁', '蒙', '闽', '宁', '青', '琼', '陕', '苏', '晋',
  11.               '皖', '湘', '新', '豫', '渝', '粤', '云', '藏', '浙']


  12. def hist_image(img):
  13.     assert img.ndim == 2
  14.     hist = [0 for i in range(256)]
  15.     img_h, img_w = img.shape[0], img.shape[1]

  16.     for row in range(img_h):
  17.         for col in range(img_w):
  18.             hist[img[row, col]] += 1
  19.     p = [hist[n] / (img_w * img_h) for n in range(256)]
  20.     p1 = np.cumsum(p)
  21.     for row in range(img_h):
  22.         for col in range(img_w):
  23.             v = img[row, col]
  24.             img[row, col] = p1[v] * 255
  25.     return img


  26. def find_board_area(img):
  27.     assert img.ndim == 2
  28.     img_h, img_w = img.shape[0], img.shape[1]
  29.     top, bottom, left, right = 0, img_h, 0, img_w
  30.     flag = False
  31.     h_proj = [0 for i in range(img_h)]
  32.     v_proj = [0 for i in range(img_w)]

  33.     for row in range(round(img_h * 0.5), round(img_h * 0.8), 3):
  34.         for col in range(img_w):
  35.             if img[row, col] == 255:
  36.                 h_proj[row] += 1
  37.         if flag == False and h_proj[row] > 12:
  38.             flag = True
  39.             top = row
  40.         if flag == True and row > top + 8 and h_proj[row] < 12:
  41.             bottom = row
  42.             flag = False

  43.     for col in range(round(img_w * 0.3), img_w, 1):
  44.         for row in range(top, bottom, 1):
  45.             if img[row, col] == 255:
  46.                 v_proj[col] += 1
  47.         if flag == False and (v_proj[col] > 10 or v_proj[col] - v_proj[col - 1] > 5):
  48.             left = col
  49.             break
  50.     return left, top, 120, bottom - top - 10


  51. def verify_scale(rotate_rect):
  52.     error = 0.4
  53.     aspect = 4  # 4.7272
  54.     min_area = 10 * (10 * aspect)
  55.     max_area = 150 * (150 * aspect)
  56.     min_aspect = aspect * (1 - error)
  57.     max_aspect = aspect * (1 + error)
  58.     theta = 30

  59.     # 宽或高为0,不满足矩形直接返回False
  60.     if rotate_rect[1][0] == 0 or rotate_rect[1][1] == 0:
  61.         return False

  62.     r = rotate_rect[1][0] / rotate_rect[1][1]
  63.     r = max(r, 1 / r)
  64.     area = rotate_rect[1][0] * rotate_rect[1][1]
  65.     if area > min_area and area < max_area and r > min_aspect and r < max_aspect:
  66.         # 矩形的倾斜角度在不超过theta
  67.         if ((rotate_rect[1][0] < rotate_rect[1][1] and rotate_rect[2] >= -90 and rotate_rect[2] < -(90 - theta)) or
  68.                 (rotate_rect[1][1] < rotate_rect[1][0] and rotate_rect[2] > -theta and rotate_rect[2] <= 0)):
  69.             return True
  70.     return False


  71. def img_Transform(car_rect, image):
  72.     img_h, img_w = image.shape[:2]
  73.     rect_w, rect_h = car_rect[1][0], car_rect[1][1]
  74.     angle = car_rect[2]

  75.     return_flag = False
  76.     if car_rect[2] == 0:
  77.         return_flag = True
  78.     if car_rect[2] == -90 and rect_w < rect_h:
  79.         rect_w, rect_h = rect_h, rect_w
  80.         return_flag = True
  81.     if return_flag:
  82.         car_img = image[int(car_rect[0][1] - rect_h / 2):int(car_rect[0][1] + rect_h / 2),
  83.                   int(car_rect[0][0] - rect_w / 2):int(car_rect[0][0] + rect_w / 2)]
  84.         return car_img

  85.     car_rect = (car_rect[0], (rect_w, rect_h), angle)
  86.     box = cv2.boxPoints(car_rect)

  87.     heigth_point = right_point = [0, 0]
  88.     left_point = low_point = [car_rect[0][0], car_rect[0][1]]
  89.     for point in box:
  90.         if left_point[0] > point[0]:
  91.             left_point = point
  92.         if low_point[1] > point[1]:
  93.             low_point = point
  94.         if heigth_point[1] < point[1]:
  95.             heigth_point = point
  96.         if right_point[0] < point[0]:
  97.             right_point = point

  98.     if left_point[1] <= right_point[1]:  # 正角度
  99.         new_right_point = [right_point[0], heigth_point[1]]
  100.         pts1 = np.float32([left_point, heigth_point, right_point])
  101.         pts2 = np.float32([left_point, heigth_point, new_right_point])  # 字符只是高度需要改变
  102.         M = cv2.getAffineTransform(pts1, pts2)
  103.         dst = cv2.warpAffine(image, M, (round(img_w * 2), round(img_h * 2)))
  104.         car_img = dst[int(left_point[1]):int(heigth_point[1]), int(left_point[0]):int(new_right_point[0])]

  105.     elif left_point[1] > right_point[1]:  # 负角度
  106.         new_left_point = [left_point[0], heigth_point[1]]
  107.         pts1 = np.float32([left_point, heigth_point, right_point])
  108.         pts2 = np.float32([new_left_point, heigth_point, right_point])  # 字符只是高度需要改变
  109.         M = cv2.getAffineTransform(pts1, pts2)
  110.         dst = cv2.warpAffine(image, M, (round(img_w * 2), round(img_h * 2)))
  111.         car_img = dst[int(right_point[1]):int(heigth_point[1]), int(new_left_point[0]):int(right_point[0])]

  112.     return car_img


  113. def pre_process(orig_img):
  114.     gray_img = cv2.cvtColor(orig_img, cv2.COLOR_BGR2GRAY)
  115.     # cv2.imshow('gray_img', gray_img)
  116.     # cv2.waitKey(0)

  117.     blur_img = cv2.blur(gray_img, (3, 3))
  118.     # cv2.imshow('blur', blur_img)
  119.     # cv2.waitKey(0)

  120.     sobel_img = cv2.Sobel(blur_img, cv2.CV_16S, 1, 0, ksize=3)
  121.     sobel_img = cv2.convertScaleAbs(sobel_img)
  122.     # cv2.imshow('sobel', sobel_img)
  123.     # cv2.waitKey(0)

  124.     hsv_img = cv2.cvtColor(orig_img, cv2.COLOR_BGR2HSV)
  125.     # cv2.imshow('hsv', hsv_img)
  126.     # cv2.waitKey(0)

  127.     h, s, v = hsv_img[:, :, 0], hsv_img[:, :, 1], hsv_img[:, :, 2]
  128.     # 黄色色调区间[26,34],蓝色色调区间:[100,124]
  129.     blue_img = (((h > 26) & (h < 34)) | ((h > 100) & (h < 124))) & (s > 70) & (v > 70)
  130.     blue_img = blue_img.astype('float32')
  131.     # cv2.imshow('blue', blue_img)
  132.     # cv2.waitKey(0)

  133.     mix_img = np.multiply(sobel_img, blue_img)
  134.     # cv2.imshow('mix', mix_img)
  135.     # cv2.waitKey(0)

  136.     mix_img = mix_img.astype(np.uint8)

  137.     ret, binary_img = cv2.threshold(mix_img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
  138.     # cv2.imshow('binary',binary_img)
  139.     # cv2.waitKey(0)

  140.     kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 5))
  141.     close_img = cv2.morphologyEx(binary_img, cv2.MORPH_CLOSE, kernel)
  142.     # cv2.imshow('close', close_img)
  143.     # cv2.waitKey(0)

  144.     return close_img


  145. # 给候选车牌区域做漫水填充算法,一方面补全上一步求轮廓可能存在轮廓歪曲的问题,
  146. # 另一方面也可以将非车牌区排除掉
  147. def verify_color(rotate_rect, src_image):
  148.     img_h, img_w = src_image.shape[:2]
  149.     mask = np.zeros(shape=[img_h + 2, img_w + 2], dtype=np.uint8)
  150.     connectivity = 4  # 种子点上下左右4邻域与种子颜色值在[loDiff,upDiff]的被涂成new_value,也可设置8邻域
  151.     loDiff, upDiff = 30, 30
  152.     new_value = 255
  153.     flags = connectivity
  154.     flags |= cv2.FLOODFILL_FIXED_RANGE  # 考虑当前像素与种子象素之间的差,不设置的话则和邻域像素比较
  155.     flags |= new_value << 8
  156.     flags |= cv2.FLOODFILL_MASK_ONLY  # 设置这个标识符则不会去填充改变原始图像,而是去填充掩模图像(mask)

  157.     rand_seed_num = 5000  # 生成多个随机种子
  158.     valid_seed_num = 200  # 从rand_seed_num中随机挑选valid_seed_num个有效种子
  159.     adjust_param = 0.1
  160.     box_points = cv2.boxPoints(rotate_rect)
  161.     box_points_x = [n[0] for n in box_points]
  162.     box_points_x.sort(reverse=False)
  163.     adjust_x = int((box_points_x[2] - box_points_x[1]) * adjust_param)
  164.     col_range = [box_points_x[1] + adjust_x, box_points_x[2] - adjust_x]
  165.     box_points_y = [n[1] for n in box_points]
  166.     box_points_y.sort(reverse=False)
  167.     adjust_y = int((box_points_y[2] - box_points_y[1]) * adjust_param)
  168.     row_range = [box_points_y[1] + adjust_y, box_points_y[2] - adjust_y]
  169.     # 如果以上方法种子点在水平或垂直方向可移动的范围很小,则采用旋转矩阵对角线来设置随机种子点
  170.     if (col_range[1] - col_range[0]) / (box_points_x[3] - box_points_x[0]) < 0.4 \
  171.             or (row_range[1] - row_range[0]) / (box_points_y[3] - box_points_y[0]) < 0.4:
  172.         points_row = []
  173.         points_col = []
  174.         for i in range(2):
  175.             pt1, pt2 = box_points[i], box_points[i + 2]
  176.             x_adjust, y_adjust = int(adjust_param * (abs(pt1[0] - pt2[0]))), int(adjust_param * (abs(pt1[1] - pt2[1])))
  177.             if (pt1[0] <= pt2[0]):
  178.                 pt1[0], pt2[0] = pt1[0] + x_adjust, pt2[0] - x_adjust
  179.             else:
  180.                 pt1[0], pt2[0] = pt1[0] - x_adjust, pt2[0] + x_adjust
  181.             if (pt1[1] <= pt2[1]):
  182.                 pt1[1], pt2[1] = pt1[1] + adjust_y, pt2[1] - adjust_y
  183.             else:
  184.                 pt1[1], pt2[1] = pt1[1] - y_adjust, pt2[1] + y_adjust
  185.             temp_list_x = [int(x) for x in np.linspace(pt1[0], pt2[0], int(rand_seed_num / 2))]
  186.             temp_list_y = [int(y) for y in np.linspace(pt1[1], pt2[1], int(rand_seed_num / 2))]
  187.             points_col.extend(temp_list_x)
  188.             points_row.extend(temp_list_y)
  189.     else:
  190.         points_row = np.random.randint(row_range[0], row_range[1], size=rand_seed_num)
  191.         points_col = np.linspace(col_range[0], col_range[1], num=rand_seed_num).astype(np.int)

  192.     points_row = np.array(points_row)
  193.     points_col = np.array(points_col)
  194.     hsv_img = cv2.cvtColor(src_image, cv2.COLOR_BGR2HSV)
  195.     h, s, v = hsv_img[:, :, 0], hsv_img[:, :, 1], hsv_img[:, :, 2]
  196.     # 将随机生成的多个种子依次做漫水填充,理想情况是整个车牌被填充
  197.     flood_img = src_image.copy()
  198.     seed_cnt = 0
  199.     for i in range(rand_seed_num):
  200.         rand_index = np.random.choice(rand_seed_num, 1, replace=False)
  201.         row, col = points_row[rand_index], points_col[rand_index]
  202.         # 限制随机种子必须是车牌背景色
  203.         if (((h[row, col] > 26) & (h[row, col] < 34)) | ((h[row, col] > 100) & (h[row, col] < 124))) & (
  204.                 s[row, col] > 70) & (v[row, col] > 70):
  205.             cv2.floodFill(src_image, mask, (col, row), (255, 255, 255), (loDiff,) * 3, (upDiff,) * 3, flags)
  206.             cv2.circle(flood_img, center=(col, row), radius=2, color=(0, 0, 255), thickness=2)
  207.             seed_cnt += 1
  208.             if seed_cnt >= valid_seed_num:
  209.                 break
  210.     # ======================调试用======================#
  211.     show_seed = np.random.uniform(1, 100, 1).astype(np.uint16)
  212.     cv2.imshow('floodfill' + str(show_seed), flood_img)
  213.     cv2.imshow('flood_mask' + str(show_seed), mask)
  214.     # ======================调试用======================#
  215.     # 获取掩模上被填充点的像素点,并求点集的最小外接矩形
  216.     mask_points = []
  217.     for row in range(1, img_h + 1):
  218.         for col in range(1, img_w + 1):
  219.             if mask[row, col] != 0:
  220.                 mask_points.append((col - 1, row - 1))
  221.     mask_rotateRect = cv2.minAreaRect(np.array(mask_points))
  222.     if verify_scale(mask_rotateRect):
  223.         return True, mask_rotateRect
  224.     else:
  225.         return False, mask_rotateRect


  226. # 车牌定位
  227. def locate_carPlate(orig_img, pred_image):
  228.     carPlate_list = []
  229.     temp1_orig_img = orig_img.copy()  # 调试用
  230.     temp2_orig_img = orig_img.copy()  # 调试用
  231.     contours, heriachy = cv2.findContours(pred_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  232.     for i, contour in enumerate(contours):
  233.         cv2.drawContours(temp1_orig_img, contours, i, (0, 255, 255), 2)
  234.         # 获取轮廓最小外接矩形,返回值rotate_rect
  235.         rotate_rect = cv2.minAreaRect(contour)
  236.         # 根据矩形面积大小和长宽比判断是否是车牌
  237.         if verify_scale(rotate_rect):
  238.             ret, rotate_rect2 = verify_color(rotate_rect, temp2_orig_img)
  239.             if ret == False:
  240.                 continue
  241.             # 车牌位置矫正
  242.             car_plate = img_Transform(rotate_rect2, temp2_orig_img)
  243.             car_plate = cv2.resize(car_plate, (car_plate_w, car_plate_h))  # 调整尺寸为后面CNN车牌识别做准备
  244.             # ========================调试看效果========================#
  245.             box = cv2.boxPoints(rotate_rect2)
  246.             for k in range(4):
  247.                 n1, n2 = k % 4, (k + 1) % 4
  248.                 cv2.line(temp1_orig_img, (box[n1][0], box[n1][1]), (box[n2][0], box[n2][1]), (255, 0, 0), 2)
  249.             cv2.imshow('opencv_' + str(i), car_plate)
  250.             # ========================调试看效果========================#
  251.             carPlate_list.append(car_plate)

  252.     cv2.imshow('contour', temp1_orig_img)
  253.     return carPlate_list


  254. # 左右切割
  255. def horizontal_cut_chars(plate):
  256.     char_addr_list = []
  257.     area_left, area_right, char_left, char_right = 0, 0, 0, 0
  258.     img_w = plate.shape[1]

  259.     # 获取车牌每列边缘像素点个数
  260.     def getColSum(img, col):
  261.         sum = 0
  262.         for i in range(img.shape[0]):
  263.             sum += round(img[i, col] / 255)
  264.         return sum;

  265.     sum = 0
  266.     for col in range(img_w):
  267.         sum += getColSum(plate, col)
  268.     # 每列边缘像素点必须超过均值的60%才能判断属于字符区域
  269.     col_limit = 0  # round(0.5*sum/img_w)
  270.     # 每个字符宽度也进行限制
  271.     charWid_limit = [round(img_w / 12), round(img_w / 5)]
  272.     is_char_flag = False

  273.     for i in range(img_w):
  274.         colValue = getColSum(plate, i)
  275.         if colValue > col_limit:
  276.             if is_char_flag == False:
  277.                 area_right = round((i + char_right) / 2)
  278.                 area_width = area_right - area_left
  279.                 char_width = char_right - char_left
  280.                 if (area_width > charWid_limit[0]) and (area_width < charWid_limit[1]):
  281.                     char_addr_list.append((area_left, area_right, char_width))
  282.                 char_left = i
  283.                 area_left = round((char_left + char_right) / 2)
  284.                 is_char_flag = True
  285.         else:
  286.             if is_char_flag == True:
  287.                 char_right = i - 1
  288.                 is_char_flag = False
  289.     # 手动结束最后未完成的字符分割
  290.     if area_right < char_left:
  291.         area_right, char_right = img_w, img_w
  292.         area_width = area_right - area_left
  293.         char_width = char_right - char_left
  294.         if (area_width > charWid_limit[0]) and (area_width < charWid_limit[1]):
  295.             char_addr_list.append((area_left, area_right, char_width))
  296.     return char_addr_list


  297. def get_chars(car_plate):
  298.     img_h, img_w = car_plate.shape[:2]
  299.     h_proj_list = []  # 水平投影长度列表
  300.     h_temp_len, v_temp_len = 0, 0
  301.     h_startIndex, h_end_index = 0, 0  # 水平投影记索引
  302.     h_proj_limit = [0.2, 0.8]  # 车牌在水平方向得轮廓长度少于20%或多余80%过滤掉
  303.     char_imgs = []

  304.     # 将二值化的车牌水平投影到Y轴,计算投影后的连续长度,连续投影长度可能不止一段
  305.     h_count = [0 for i in range(img_h)]
  306.     for row in range(img_h):
  307.         temp_cnt = 0
  308.         for col in range(img_w):
  309.             if car_plate[row, col] == 255:
  310.                 temp_cnt += 1
  311.         h_count[row] = temp_cnt
  312.         if temp_cnt / img_w < h_proj_limit[0] or temp_cnt / img_w > h_proj_limit[1]:
  313.             if h_temp_len != 0:
  314.                 h_end_index = row - 1
  315.                 h_proj_list.append((h_startIndex, h_end_index))
  316.                 h_temp_len = 0
  317.             continue
  318.         if temp_cnt > 0:
  319.             if h_temp_len == 0:
  320.                 h_startIndex = row
  321.                 h_temp_len = 1
  322.             else:
  323.                 h_temp_len += 1
  324.         else:
  325.             if h_temp_len > 0:
  326.                 h_end_index = row - 1
  327.                 h_proj_list.append((h_startIndex, h_end_index))
  328.                 h_temp_len = 0

  329.     # 手动结束最后得水平投影长度累加
  330.     if h_temp_len != 0:
  331.         h_end_index = img_h - 1
  332.         h_proj_list.append((h_startIndex, h_end_index))
  333.     # 选出最长的投影,该投影长度占整个截取车牌高度的比值必须大于0.5
  334.     h_maxIndex, h_maxHeight = 0, 0
  335.     for i, (start, end) in enumerate(h_proj_list):
  336.         if h_maxHeight < (end - start):
  337.             h_maxHeight = (end - start)
  338.             h_maxIndex = i
  339.     if h_maxHeight / img_h < 0.5:
  340.         return char_imgs
  341.     chars_top, chars_bottom = h_proj_list[h_maxIndex][0], h_proj_list[h_maxIndex][1]

  342.     plates = car_plate[chars_top:chars_bottom + 1, :]
  343.     cv2.imwrite('carIdentityData/opencv_output/car.jpg', car_plate)
  344.     cv2.imwrite('carIdentityData/opencv_output/plate.jpg', plates)
  345.     char_addr_list = horizontal_cut_chars(plates)

  346.     for i, addr in enumerate(char_addr_list):
  347.         char_img = car_plate[chars_top:chars_bottom + 1, addr[0]:addr[1]]
  348.         char_img = cv2.resize(char_img, (char_w, char_h))
  349.         char_imgs.append(char_img)
  350.     return char_imgs


  351. def extract_char(car_plate):
  352.     gray_plate = cv2.cvtColor(car_plate, cv2.COLOR_BGR2GRAY)
  353.     ret, binary_plate = cv2.threshold(gray_plate, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
  354.     char_img_list = get_chars(binary_plate)
  355.     return char_img_list


  356. def cnn_select_carPlate(plate_list, model_path):
  357.     if len(plate_list) == 0:
  358.         return False, plate_list
  359.     g1 = tf.Graph()
  360.     sess1 = tf.Session(graph=g1)
  361.     with sess1.as_default():
  362.         with sess1.graph.as_default():
  363.             model_dir = os.path.dirname(model_path)
  364.             saver = tf.train.import_meta_graph(model_path)
  365.             saver.restore(sess1, tf.train.latest_checkpoint(model_dir))
  366.             graph = tf.get_default_graph()
  367.             net1_x_place = graph.get_tensor_by_name('x_place:0')
  368.             net1_keep_place = graph.get_tensor_by_name('keep_place:0')
  369.             net1_out = graph.get_tensor_by_name('out_put:0')

  370.             input_x = np.array(plate_list)
  371.             net_outs = tf.nn.softmax(net1_out)
  372.             preds = tf.argmax(net_outs, 1)  # 预测结果
  373.             probs = tf.reduce_max(net_outs, reduction_indices=[1])  # 结果概率值
  374.             pred_list, prob_list = sess1.run([preds, probs], feed_dict={net1_x_place: input_x, net1_keep_place: 1.0})
  375.             # 选出概率最大的车牌
  376.             result_index, result_prob = -1, 0.
  377.             for i, pred in enumerate(pred_list):
  378.                 if pred == 1 and prob_list[i] > result_prob:
  379.                     result_index, result_prob = i, prob_list[i]
  380.             if result_index == -1:
  381.                 return False, plate_list[0]
  382.             else:
  383.                 return True, plate_list[result_index]


  384. def cnn_recongnize_char(img_list, model_path):
  385.     g2 = tf.Graph()
  386.     sess2 = tf.Session(graph=g2)
  387.     text_list = []
  388.     pro_list = []

  389.     if len(img_list) == 0:
  390.         return text_list
  391.     with sess2.as_default():
  392.         with sess2.graph.as_default():
  393.             model_dir = os.path.dirname(model_path)
  394.             saver = tf.train.import_meta_graph(model_path)
  395.             saver.restore(sess2, tf.train.latest_checkpoint(model_dir))
  396.             graph = tf.get_default_graph()
  397.             net2_x_place = graph.get_tensor_by_name('x_place:0')
  398.             net2_keep_place = graph.get_tensor_by_name('keep_place:0')
  399.             net2_out = graph.get_tensor_by_name('out_put:0')

  400.             data = np.array(img_list)
  401.             # 数字、字母、汉字,从67维向量找到概率最大的作为预测结果
  402.             net_out = tf.nn.softmax(net2_out)
  403.             preds = tf.argmax(net_out, 1)
  404.             probs = tf.reduce_max(net_out, reduction_indices=[1])  # 结果概率值
  405.             my_preds, my_probs = sess2.run([preds, probs], feed_dict={net2_x_place: data, net2_keep_place: 1.0})
  406.             # print(my_preds)
  407.             print(my_probs)
  408.             for i in my_preds:
  409.                 text_list.append(char_table[i])
  410.             prob = 0
  411.             for i in my_probs:
  412.                 prob = prob + i
  413.             prob = prob / len(my_probs)
  414.             return text_list, prob


  415. # if __name__ == '__main__':
  416. #     cur_dir = sys.path[0]
  417. #     car_plate_w,car_plate_h = 136,36
  418. #     char_w,char_h = 20,20
  419. #     plate_model_path = os.path.join(cur_dir, './carIdentityData/model/plate_recongnize/model.ckpt-510.meta')
  420. #     char_model_path = os.path.join(cur_dir,'./carIdentityData/model/char_recongnize/model.ckpt-520.meta')
  421. #     img = cv2.imread('carIdentityData/images/43.jpg')
  422. #
  423. #     # 预处理
  424. #     pred_img = pre_process(img)
  425. #     # cv2.imshow('pred_img', pred_img)
  426. #     # cv2.waitKey(0)
  427. #
  428. #     # 车牌定位
  429. #     car_plate_list = locate_carPlate(img,pred_img)
  430. #
  431. #     # CNN车牌过滤
  432. #     ret,car_plate = cnn_select_carPlate(car_plate_list,plate_model_path)
  433. #     if ret == False:
  434. #         print("未检测到车牌")
  435. #         sys.exit(-1)
  436. #     # cv2.imshow('cnn_plate',car_plate)
  437. #     # cv2.waitKey(0)
  438. #
  439. #     # 字符提取
  440. #     char_img_list = extract_char(car_plate)
  441. #     print(len(char_img_list))
  442. #     # CNN字符识别
  443. #     text,pro = cnn_recongnize_char(char_img_list,char_model_path)
  444. #     print(text)
  445. #     print(pro)
  446. def recognizePlatestr(src):
  447.     cur_dir = sys.path[0]
  448.     car_plate_w, car_plate_h = 136, 36
  449.     char_w, char_h = 20, 20
  450.     plate_model_path = os.path.join(cur_dir, './carIdentityData/model/plate_recongnize/model.ckpt-510.meta')
  451.     char_model_path = os.path.join(cur_dir, './carIdentityData/model/char_recongnize/model.ckpt-520.meta')
  452.     # img = cv2.imread('./carIdentityData/images/32.jpg')
  453.     img = cv2.imread(src)

  454.     # 预处理
  455.     pred_img = pre_process(img)
  456.     # cv2.imshow('pred_img', pred_img)
  457.     # cv2.waitKey(0)

  458.     # 车牌定位
  459.     car_plate_list = locate_carPlate(img, pred_img)

  460.     # CNN车牌过滤
  461.     ret, car_plate = cnn_select_carPlate(car_plate_list, plate_model_path)
  462.     if ret == False:
  463.         print("未检测到车牌")
  464.         sys.exit(-1)
  465.     # 字符提取
  466.     char_img_list = extract_char(car_plate)
  467.     print(len(char_img_list))
  468.     # CNN字符识别
  469.     text, confidence = cnn_recongnize_char(char_img_list, char_model_path)
  470.     confidence = str(round(confidence, 3))
  471.     str1 = ''.join(text)
  472.     laststr = str1 + "#" + confidence
  473.     return laststr


  474. from xmlrpc.server import SimpleXMLRPCServer

  475. server = SimpleXMLRPCServer(('localhost', 8888))  # 初始化
  476. server.register_function(recognizePlatestr, "get_platestr")  # 注册函数
  477. print("Listening for Client")
  478. server.serve_forever()  # 保持等待调用状态

  479. # str = recognizePlatestr('./carIdentityData/images/23.jpg')
  480. # print(str)
复制代码




(carPlateIdentity.py不添加rpc server代码时,直接右击run是能够得出结果。)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-2 13:56:47 | 显示全部楼层
愿你 发表于 2020-4-2 13:55
首先,我要实现的小程序是从微信小程序端上传一张车牌图片到后端(这里的后端用django搭建),django后台 ...

但是现在控制台出现错误
  1. ====
  2. 111
  3. D:\pycharm\djangocode\project6/media/media/wx09b36be785d8846c.o6zAJs2gF51BlvNkRFJvDsCl65Ws.CPvzAqHuWWDX9395e6d37e306b59ac9b49_
  4. dsxXny6.jpg
  5. Internal Server Error: /upload_handle/
  6. Traceback (most recent call last):
  7.   File "D:\Anaconda\envs\python363\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
  8.     response = get_response(request)
  9.   File "D:\Anaconda\envs\python363\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
  10.     response = self.process_exception_by_middleware(e, request)
  11.   File "D:\Anaconda\envs\python363\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
  12.     response = wrapped_callback(request, *callback_args, **callback_kwargs)
  13.   File "D:\pycharm\djangocode\project6\myApp\views.py", line 80, in upload_handle
  14.     print(server.get_platestr(path))
  15.   File "D:\Anaconda\envs\python363\lib\xmlrpc\client.py", line 1112, in __call__
  16.     return self.__send(self.__name, args)
  17.   File "D:\Anaconda\envs\python363\lib\xmlrpc\client.py", line 1452, in __request
  18.     verbose=self.__verbose
  19.   File "D:\Anaconda\envs\python363\lib\xmlrpc\client.py", line 1154, in request
  20.     return self.single_request(host, handler, request_body, verbose)
  21.   File "D:\Anaconda\envs\python363\lib\xmlrpc\client.py", line 1170, in single_request
  22.     return self.parse_response(resp)
  23.   File "D:\Anaconda\envs\python363\lib\xmlrpc\client.py", line 1342, in parse_response
  24.     return u.close()
  25.   File "D:\Anaconda\envs\python363\lib\xmlrpc\client.py", line 656, in close
  26.     raise Fault(**self._stack[0])
  27. xmlrpc.client.Fault: <Fault 1: "<class 'ValueError'>:not enough values to unpack (expected 3, got 2)">
  28. [02/Apr/2020 13:38:24] "POST /upload_handle/ HTTP/1.1" 500 96213
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-3 07:27:21 | 显示全部楼层
没学过 Django ...
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-11 16:01:24 | 显示全部楼层

谢啦~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-11 16:01:55 | 显示全部楼层

谢啦~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-12 21:50

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表