• 相机实时进行透视变换矫正 并用streamlit做个界面


    1. import cv2
    2. import numpy as np
    3. def get_rectangle_corners(image, resize_height, prev_rectangle=None, stability_factor=12):
    4. def process_image(image, height):
    5. ratio = image.shape[0] / height
    6. image = cv2.resize(image, (int(image.shape[1] / ratio), height))
    7. gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    8. gray = cv2.GaussianBlur(gray, (3, 3), 0)
    9. edges = cv2.Canny(gray, 25, 125)
    10. return edges, ratio
    11. def find_rectangle(edges):
    12. contours, _ = cv2.findContours(edges.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    13. contours = sorted(contours, key=cv2.contourArea, reverse=True)[:5]
    14. for contour in contours:
    15. peri = cv2.arcLength(contour, True)
    16. approx = cv2.approxPolyDP(contour, 0.02 * peri, True)
    17. if len(approx) == 4:
    18. return approx
    19. edges, ratio = process_image(image, resize_height)
    20. rectangle = find_rectangle(edges)
    21. if rectangle is not None:
    22. rectangle = rectangle.reshape(4, 2) * ratio
    23. rectangle = [[int(point[0]), int(point[1])] for point in rectangle]
    24. # if prev rectangle exists and the change is smaller than the stability factor, use the previous rectangle
    25. if prev_rectangle is not None:
    26. diff = np.abs(np.array(prev_rectangle) - np.array(rectangle))
    27. if np.all(diff < stability_factor):
    28. return prev_rectangle
    29. return rectangle
    30. else:
    31. return prev_rectangle # if no rectangle detected, use the previous one
    32. prev_rectangle = None
    33. dst = np.float32([[0, 0], [0, 488],[337, 488],[337, 0]])
    34. cap = cv2.VideoCapture(0)
    35. while True:
    36. ret, frame = cap.read()
    37. if ret:
    38. rectangle = get_rectangle_corners(frame, 500, prev_rectangle)
    39. prev_rectangle = rectangle # save the rectangle for the next frame
    40. print(rectangle)
    41. if rectangle is not None:
    42. src = np.float32(rectangle)
    43. m = cv2.getPerspectiveTransform(src, dst)
    44. result = cv2.warpPerspective(frame, m, (337, 488))
    45. cv2.imshow("src", frame)
    46. cv2.imshow("result", result)
    47. if cv2.waitKey(1) & 0xFF == ord('q'):
    48. break
    49. cap.release()
    50. cv2.destroyAllWindows()

    streamlit界面

    1. import streamlit as st
    2. from cnstd import CnStd
    3. from cnocr import CnOcr
    4. import cv2
    5. import numpy as np
    6. import pandas as pd
    7. from PIL import Image
    8. def get_rectangle_corners(image, resize_height, prev_rectangle=None, stability_factor=12):
    9. def process_image(image, height):
    10. ratio = image.shape[0] / height
    11. image = cv2.resize(image, (int(image.shape[1] / ratio), height))
    12. gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    13. gray = cv2.GaussianBlur(gray, (3, 3), 0)
    14. edges = cv2.Canny(gray, 50, 100)
    15. return edges, ratio
    16. def find_rectangle(edges):
    17. contours, _ = cv2.findContours(edges.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    18. contours = sorted(contours, key=cv2.contourArea, reverse=True)[:1]
    19. for contour in contours:
    20. peri = cv2.arcLength(contour, True)
    21. approx = cv2.approxPolyDP(contour, 0.02 * peri, True)
    22. if len(approx) == 4:
    23. return approx
    24. edges, ratio = process_image(image, resize_height)
    25. rectangle = find_rectangle(edges)
    26. if rectangle is not None:
    27. rectangle = rectangle.reshape(4, 2) * ratio
    28. rectangle = [[int(point[0]), int(point[1])] for point in rectangle]
    29. if prev_rectangle is not None:
    30. diff = np.abs(np.array(prev_rectangle) - np.array(rectangle))
    31. if np.all(diff < stability_factor):
    32. return prev_rectangle
    33. return rectangle
    34. else:
    35. return prev_rectangle # if no rectangle detected, use the previous one
    36. # Code where the two scripts are fused together
    37. dst = np.float32([[0, 0], [0, 588],[640, 588],[640, 0]])
    38. prev_rectangle = None
    39. cap = cv2.VideoCapture(0)
    40. std = CnStd()
    41. cn_ocr = CnOcr()
    42. st.sidebar.title("易读写")
    43. option = st.sidebar.selectbox('请选择要运行的功能', ('显示矫正后画面', '图片转文字'))
    44. # 定义两个图像显示窗口
    45. FRAME_WINDOW_RAW = st.image([])
    46. FRAME_WINDOW_TRANSFORMED = st.image([])
    47. # 需要实时显示矫正后画面
    48. if option == '显示矫正后画面':
    49. run = st.checkbox('开始运行')
    50. FRAME_WINDOW = st.image([])
    51. alpha = st.sidebar.slider('亮度调节 Brightness', min_value=0.0, max_value=3.0,
    52. value=1.0) # Add a slider for brightness
    53. angle = st.sidebar.slider('视角调节 Rotation', 0, 360, 0) # Add a slider for rotation
    54. if run:
    55. while True:
    56. ret, frame = cap.read()
    57. if not ret:
    58. st.write("Can't receive frame (Stream end?). Exiting..")
    59. break
    60. rectangle = get_rectangle_corners(frame, 500, prev_rectangle)
    61. prev_rectangle = rectangle # save the rectangle for the next frame
    62. if rectangle is not None:
    63. src = np.float32(rectangle)
    64. m = cv2.getPerspectiveTransform(src, dst)
    65. result = cv2.warpPerspective(frame, m, (640, 588))
    66. raw_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # Convert BGR to RGB for raw frame
    67. img_raw = Image.fromarray(raw_frame)
    68. FRAME_WINDOW_RAW.image(img_raw) # Show raw frame
    69. result = cv2.cvtColor(result, cv2.COLOR_BGR2RGB) # Convert BGR to RGB for transformed
    70. result = cv2.convertScaleAbs(result, alpha=alpha, beta=0)
    71. img_transformed = Image.fromarray(result)
    72. FRAME_WINDOW_TRANSFORMED.image(img_transformed) # Show transformed result
    73. else:
    74. st.write('Stopped')
    75. cap.release()
    76. elif option == '图片转文字':
    77. uploaded_file = st.sidebar.file_uploader("选择一个图片文件")
    78. if uploaded_file is not None:
    79. img = Image.open(uploaded_file)
    80. st.image(img, caption='Uploaded Image.', use_column_width=True)
    81. if st.sidebar.button('开始运行'):
    82. # Copy and adapt your code here
    83. with st.spinner('OCR is in progress...'):
    84. np_img = np.array(img) # Convert PIL Image to numpy array
    85. box_infos = std.detect(np_img)
    86. text = []
    87. for box_info in box_infos['detected_texts']:
    88. cropped_img = box_info['cropped_img']
    89. ocr_res = cn_ocr.ocr_for_single_line(cropped_img)
    90. text.append(ocr_res['text'])
    91. st.subheader("Extracted text:")
    92. for line in text:
    93. st.write(line)
    94. st.success('Text extraction complete')

  • 相关阅读:
    Ros2第一个节点程序调试(C++)
    Spark SQL数据源 - Parquet文件
    含文档+PPT+源码等]精品基于PHP实现的网上买卖管理系统[包运行成功]计算机PHP毕业设计项目源码
    基于HTML+CSS+JavaScript+Bootstarp响应式健身网站(web前端期末大作业)
    华为OD机试 - TLV格式 - 逻辑分析(Java 2023 B卷 100分)
    【已解决】windows电脑连蓝牙耳机总是断断续续?
    python通过导入自定义dll实现显存释放
    《算法导论》15.5 最优二叉搜索树(含C++代码)
    【Mac】破解死循环,成功安装 Homebrew、curl、wget,快速配置 zsh
    成语词典查询易语言代码
  • 原文地址:https://blog.csdn.net/qq_53821866/article/details/139657187