最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Python和OpenCV實(shí)現(xiàn)實(shí)時(shí)文檔掃描的全流程

 更新時(shí)間:2025年09月18日 09:53:57   作者:dlraba802  
在日常工作與學(xué)習(xí)中,我們經(jīng)常需要將紙質(zhì)文檔轉(zhuǎn)化為電子版本,所以本文將詳細(xì)講解如何基于 Python 和 OpenCV 構(gòu)建實(shí)時(shí)文檔掃描系統(tǒng),涵蓋圖像預(yù)處理、輪廓檢測(cè)、透視變換、二值化等核心步驟,需要的朋友可以參考下

在日常工作與學(xué)習(xí)中,我們經(jīng)常需要將紙質(zhì)文檔轉(zhuǎn)化為電子版本。雖然手機(jī)端有許多掃描 APP,但了解其背后的技術(shù)原理,并使用 OpenCV 手動(dòng)實(shí)現(xiàn)一個(gè)實(shí)時(shí)文檔掃描工具,不僅能加深對(duì)計(jì)算機(jī)視覺(jué)的理解,還能根據(jù)需求靈活定制功能。本文將詳細(xì)講解如何基于 Python 和 OpenCV 構(gòu)建實(shí)時(shí)文檔掃描系統(tǒng),涵蓋圖像預(yù)處理、輪廓檢測(cè)、透視變換、二值化等核心步驟。

一、項(xiàng)目核心原理與目標(biāo)

1.1 核心目標(biāo)

通過(guò)計(jì)算機(jī)攝像頭實(shí)時(shí)采集圖像,自動(dòng)識(shí)別畫(huà)面中的文檔區(qū)域,對(duì)文檔進(jìn)行透視矯正(解決傾斜、變形問(wèn)題),并轉(zhuǎn)化為清晰的二值化圖像(模擬掃描件效果),最終實(shí)現(xiàn)類(lèi)似專(zhuān)業(yè)掃描儀的功能。

1.2 關(guān)鍵技術(shù)原理

文檔掃描的核心是解決 “從傾斜變形到正面對(duì)齊” 的問(wèn)題,主要依賴(lài)以下兩項(xiàng)計(jì)算機(jī)視覺(jué)技術(shù):

  • 透視變換(Perspective Transformation):將不規(guī)則的四邊形文檔區(qū)域(如傾斜拍攝的文檔)映射為規(guī)則的矩形,消除視角帶來(lái)的變形,得到文檔的正視圖。
  • 輪廓檢測(cè)(Contour Detection):從圖像中識(shí)別出文檔的邊緣輪廓,確定文檔的四個(gè)頂點(diǎn)坐標(biāo),為透視變換提供關(guān)鍵參數(shù)。

二、項(xiàng)目環(huán)境準(zhǔn)備

在開(kāi)始編寫(xiě)代碼前,需要搭建基礎(chǔ)的開(kāi)發(fā)環(huán)境,核心依賴(lài)兩個(gè) Python 庫(kù):

  • OpenCV:用于圖像采集、預(yù)處理、輪廓檢測(cè)、透視變換等核心操作。
  • NumPy:用于數(shù)值計(jì)算,尤其是矩陣運(yùn)算(透視變換需處理坐標(biāo)矩陣)。

安裝命令

打開(kāi)終端,執(zhí)行以下命令安裝依賴(lài)庫(kù):

pip install opencv-python numpy 

三、核心功能模塊拆解與實(shí)現(xiàn)

整個(gè)實(shí)時(shí)文檔掃描系統(tǒng)分為 5 個(gè)核心模塊,我們將逐一講解每個(gè)模塊的代碼邏輯與實(shí)現(xiàn)思路。

模塊 1:坐標(biāo)排序(order_points)—— 確定文檔頂點(diǎn)順序

透視變換需要明確文檔的四個(gè)頂點(diǎn)的正確順序(左上、右上、右下、左下),否則會(huì)導(dǎo)致變換后圖像錯(cuò)亂。order_points函數(shù)通過(guò)坐標(biāo)的 “和” 與 “差” 特性,自動(dòng)排序四個(gè)頂點(diǎn)。

代碼實(shí)現(xiàn)

import numpy as np
import cv2
 
def order_points(pts):
    # 初始化4個(gè)頂點(diǎn)的坐標(biāo)(左上、右上、右下、左下)
    rect = np.zeros((4, 2), dtype="float32")
    
    # 1. 計(jì)算每個(gè)點(diǎn)的x+y之和:左上點(diǎn)的和最小,右下點(diǎn)的和最大
    s = pts.sum(axis=1)
    rect[0] = pts[np.argmin(s)]  # 左上(tl)
    rect[2] = pts[np.argmax(s)]  # 右下(br)
    
    # 2. 計(jì)算每個(gè)點(diǎn)的y-x之差(np.diff默認(rèn)是后減前,即y-x):右上點(diǎn)的差最小,左下點(diǎn)的差最大
    diff = np.diff(pts, axis=1)
    rect[1] = pts[np.argmin(diff)]  # 右上(tr)
    rect[3] = pts[np.argmax(diff)]  # 左下(bl)
    
    return rect

邏輯解析

  • 坐標(biāo)和(s = x + y):對(duì)于傾斜的文檔,左上角頂點(diǎn)(x 小、y ?。┑暮妥钚?,右下角頂點(diǎn)(x 大、y 大)的和最大,可直接定位這兩個(gè)點(diǎn)。
  • 坐標(biāo)差(diff = y - x):右上角頂點(diǎn)(x 大、y ?。┑牟钭钚?,左下角頂點(diǎn)(x 小、y 大)的差最大,以此定位剩余兩個(gè)點(diǎn)。

模塊 2:透視變換(four_point_transform)—— 矯正文檔形態(tài)

透視變換的核心是通過(guò)透視矩陣(M) 將不規(guī)則的文檔四邊形映射為規(guī)則矩形。該過(guò)程需要兩個(gè)關(guān)鍵參數(shù):

  1. 原始圖像中文檔的四個(gè)頂點(diǎn)(已通過(guò)order_points排序)。
  2. 目標(biāo)矩形的四個(gè)頂點(diǎn)(通常設(shè)為左上角 (0,0)、右上角 (maxWidth,0)、右下角 (maxWidth,maxHeight)、左下角 (0,maxHeight))。

代碼實(shí)現(xiàn)

def four_point_transform(image, pts):
    # 1. 獲取排序后的四個(gè)頂點(diǎn)
    rect = order_points(pts)
    (tl, tr, br, bl) = rect  # 左上、右上、右下、左下
    
    # 2. 計(jì)算目標(biāo)矩形的寬度(取文檔左右兩邊的最大長(zhǎng)度,避免變形)
    widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))  # 下邊長(zhǎng)
    widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))  # 上邊長(zhǎng)
    maxWidth = max(int(widthA), int(widthB))  # 目標(biāo)寬度
    
    # 3. 計(jì)算目標(biāo)矩形的高度(取文檔上下兩邊的最大長(zhǎng)度)
    heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))  # 右邊長(zhǎng)
    heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))  # 左邊長(zhǎng)
    maxHeight = max(int(heightA), int(heightB))  # 目標(biāo)高度
    
    # 4. 定義目標(biāo)矩形的四個(gè)頂點(diǎn)
    dst = np.array([
        [0, 0],                  # 左上
        [maxWidth - 1, 0],       # 右上(減1是因?yàn)橄袼厮饕龔?開(kāi)始)
        [maxWidth - 1, maxHeight - 1],  # 右下
        [0, maxHeight - 1]], dtype="float32")  # 左下
    
    # 5. 計(jì)算透視矩陣M
    M = cv2.getPerspectiveTransform(rect, dst)
    
    # 6. 應(yīng)用透視變換,得到矯正后的圖像
    warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
    
    return warped

關(guān)鍵函數(shù)解析

  • cv2.getPerspectiveTransform(rect, dst):根據(jù)原始頂點(diǎn)(rect)和目標(biāo)頂點(diǎn)(dst),計(jì)算 3x3 的透視矩陣 M,該矩陣描述了從原始圖像到目標(biāo)圖像的映射關(guān)系。
  • cv2.warpPerspective(image, M, (maxWidth, maxHeight)):應(yīng)用透視矩陣 M,將原始圖像變換為目標(biāo)尺寸(maxWidth, maxHeight)的正視圖。

模塊 3:圖像預(yù)處理與輪廓檢測(cè) —— 定位文檔區(qū)域

要從攝像頭實(shí)時(shí)圖像中識(shí)別文檔,需要先對(duì)圖像進(jìn)行預(yù)處理(降噪、邊緣檢測(cè)),再通過(guò)輪廓檢測(cè)提取文檔的邊緣。

預(yù)處理邏輯

  1. 灰度化(cvtColor):將彩色 圖像轉(zhuǎn)為灰度圖像,減少計(jì)算量(彩色 圖像有 3 個(gè)通道,灰度圖僅 1 個(gè)通道)。
  2. 高斯模糊(GaussianBlur):通過(guò)卷積操作平滑圖像,減少噪聲干擾,避免邊緣檢測(cè)時(shí)誤識(shí)別噪聲為邊緣。
  3. 邊緣檢測(cè)(Canny):通過(guò)計(jì)算像素梯度,提取圖像中的邊緣信息,為輪廓檢測(cè)做準(zhǔn)備。

輪廓檢測(cè)邏輯

  1. 提取輪廓(findContours):從邊緣圖像中提取所有外部輪廓(cv2.RETR_EXTERNAL表示只取最外層輪廓)。
  2. 篩選輪廓(sorted + contourArea):按輪廓面積降序排序,取前 3 個(gè)最大輪廓(文檔通常是畫(huà)面中面積最大的物體)。
  3. 多邊形逼近(approxPolyDP):將不規(guī)則輪廓逼近為多邊形,通過(guò)判斷 “面積是否足夠大” 和 “是否為四邊形”,確定文檔輪廓(文檔通常是四邊形)。

核心代碼片段

# 圖像預(yù)處理
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 灰度化
gray = cv2.GaussianBlur(gray, (5, 5), 0)  # 高斯模糊(5x5卷積核,標(biāo)準(zhǔn)差0)
edged = cv2.Canny(gray, 15, 45)  # 邊緣檢測(cè)(低閾值15,高閾值45)
 
# 輪廓檢測(cè)與篩選
cnts = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]  # 提取外部輪廓
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:3]  # 按面積降序,取前3個(gè)
 
# 遍歷輪廓,判斷是否為文檔(四邊形+面積足夠大)
for c in cnts:
    peri = cv2.arcLength(c, True)  # 計(jì)算輪廓周長(zhǎng)(True表示輪廓閉合)
    # 多邊形逼近:epsilon=0.05*peri(逼近精度,值越小越接近原輪廓)
    approx = cv2.approxPolyDP(c, 0.05 * peri, True)
    area = cv2.contourArea(approx)  # 計(jì)算逼近后多邊形的面積
    
    # 條件:面積>20000(過(guò)濾小物體)且頂點(diǎn)數(shù)=4(文檔為四邊形)
    if area > 20000 and len(approx) == 4:
        screenCnt = approx  # 確定文檔輪廓
        print("檢測(cè)到文檔,輪廓面積:", area)
        break

模塊 4:二值化處理 —— 生成掃描件效果

透視變換后的文檔圖像仍為灰度圖,通過(guò)二值化處理可將其轉(zhuǎn)化為 “黑底白字” 或 “白底黑字” 的清晰圖像,模擬專(zhuān)業(yè)掃描件的效果。

代碼實(shí)現(xiàn)

# 對(duì)透視變換后的圖像進(jìn)行二值化
warped_gray = cv2.cvtColor(warped_result, cv2.COLOR_BGR2GRAY)
# 自動(dòng)閾值二值化(THRESH_OTSU:自動(dòng)計(jì)算最優(yōu)閾值,避免手動(dòng)調(diào)參)
ref_result = cv2.threshold(warped_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

關(guān)鍵函數(shù)解析

  • cv2.threshold(src, thresh, maxval, type)
    • src:輸入灰度圖。
    • thresh:閾值(設(shè)為 0,由THRESH_OTSU自動(dòng)計(jì)算)。
    • maxval:超過(guò)閾值的像素值(設(shè)為 255,即白色)。
    • typeTHRESH_BINARY表示 “超過(guò)閾值設(shè)為 maxval,否則設(shè)為 0”;THRESH_OTSU表示自動(dòng)計(jì)算最優(yōu)閾值。

模塊 5:實(shí)時(shí)攝像頭采集與窗口顯示

通過(guò)cv2.VideoCapture調(diào)用計(jì)算機(jī)攝像頭,實(shí)時(shí)采集圖像并處理,同時(shí)通過(guò)自定義的cv_show函數(shù)顯示各步驟的結(jié)果(原始圖像、邊緣檢測(cè)、輪廓、矯正后圖像、二值化圖像)。

代碼實(shí)現(xiàn)

# 自定義顯示函數(shù)(不自動(dòng)關(guān)閉窗口,需按q退出)
def cv_show(name, img):
    cv2.imshow(name, img)
 
# 初始化攝像頭(0表示默認(rèn)攝像頭)
cap = cv2.VideoCapture(0)
 
# 檢查攝像頭是否正常打開(kāi)
if not cap.isOpened():
    print("無(wú)法打開(kāi)攝像頭")
    exit()
 
# 實(shí)時(shí)采集與處理循環(huán)
while True:
    ret, image = cap.read()  # 讀取一幀圖像(ret:是否讀取成功,image:圖像數(shù)據(jù))
    orig = image.copy()  # 保存原始圖像副本
    
    if not ret:
        print("無(wú)法讀取攝像頭幀")
        break
    
    # 1. 顯示原始圖像
    cv_show("Original", image)
    
    # 2. 圖像預(yù)處理與輪廓檢測(cè)(此處省略,見(jiàn)模塊3)
    # ...(預(yù)處理、輪廓檢測(cè)代碼)...
    
    # 3. 若檢測(cè)到文檔,顯示結(jié)果
    if flag == 1:
        # 繪制文檔輪廓
        image_with_doc = cv2.drawContours(orig.copy(), [screenCnt], 0, (0, 255, 0), 2)
        cv_show("Document Detection", image_with_doc)
        
        # 透視變換
        warped_result = four_point_transform(orig, screenCnt.reshape(4, 2))
        cv_show("Warped", warped_result)
        
        # 二值化
        ref_result = cv2.threshold(cv2.cvtColor(warped_result, cv2.COLOR_BGR2GRAY), 
                                   0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
        cv_show("Binarized", ref_result)
    
    # 按下'q'鍵退出循環(huán)(waitKey(1):等待1ms,返回按鍵ASCII碼)
    if cv2.waitKey(1) == ord('q'):
        break
 
# 釋放攝像頭資源,關(guān)閉所有窗口
cap.release()
cv2.destroyAllWindows()

四、完整代碼整合與運(yùn)行說(shuō)明

4.1 完整代碼

將上述模塊整合,得到完整的實(shí)時(shí)文檔掃描代碼:

import numpy as np
import cv2
 
 
def order_points(pts):
    rect = np.zeros((4, 2), dtype="float32")
    s = pts.sum(axis=1)
    rect[0] = pts[np.argmin(s)]
    rect[2] = pts[np.argmax(s)]
    diff = np.diff(pts, axis=1)
    rect[1] = pts[np.argmin(diff)]
    rect[3] = pts[np.argmax(diff)]
    return rect
 
 
def four_point_transform(image, pts):
    rect = order_points(pts)
    (tl, tr, br, bl) = rect
    widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
    widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
    maxWidth = max(int(widthA), int(widthB))
    heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
    heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
    maxHeight = max(int(heightA), int(heightB))
    dst = np.array([
        [0, 0],
        [maxWidth - 1, 0],
        [maxWidth - 1, maxHeight - 1],
        [0, maxHeight - 1]], dtype="float32")
    M = cv2.getPerspectiveTransform(rect, dst)
    warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
    return warped
 
 
def cv_show(name, img):
    cv2.imshow(name, img)
 
 
if __name__ == "__main__":
    cap = cv2.VideoCapture(0)
    if not cap.isOpened():
        print("Cannot open camera")
        exit()
 
    while True:
        flag = 0
        ret, image = cap.read()
        orig = image.copy()
        if not ret:
            print("不能讀取攝像頭")
            break
 
        # 顯示原始圖像
        cv_show("Original", image)
 
        # 圖像預(yù)處理
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        gray = cv2.GaussianBlur(gray, (5, 5), 0)
        edged = cv2.Canny(gray, 15, 45)
        cv_show("Edge Detection", edged)
 
        # 輪廓檢測(cè)與篩選
        cnts = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
        cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:3]
        image_contours = cv2.drawContours(image.copy(), cnts, -1, (0, 255, 0), 2)
        cv_show("Contours", image_contours)
 
        # 識(shí)別文檔輪廓
        for c in cnts:
            peri = cv2.arcLength(c, True)
            approx = cv2.approxPolyDP(c, 0.05 * peri, True)
            area = cv2.contourArea(approx)
 
            if area > 20000 and len(approx) == 4:
                screenCnt = approx
                flag = 1
                print(f"檢測(cè)到文檔,周長(zhǎng):{peri:.2f},面積:{area:.2f}")
 
                # 顯示文檔檢測(cè)結(jié)果
                image_with_doc = cv2.drawContours(orig.copy(), [screenCnt], 0, (0, 255, 0), 2)
                cv_show("Document Detection", image_with_doc)
 
                # 透視變換
                warped_result = four_point_transform(orig, screenCnt.reshape(4, 2))
                cv_show("Warped", warped_result)
 
                # 二值化
                warped_gray = cv2.cvtColor(warped_result, cv2.COLOR_BGR2GRAY)
                ref_result = cv2

以上就是基于Python和OpenCV實(shí)現(xiàn)實(shí)時(shí)文檔掃描的全流程的詳細(xì)內(nèi)容,更多關(guān)于Python OpenCV實(shí)時(shí)文檔掃描的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Flask-Docs自動(dòng)生成Api文檔安裝使用教程

    Flask-Docs自動(dòng)生成Api文檔安裝使用教程

    這篇文章主要為大家介紹了Flask-Docs自動(dòng)生成Api文檔安裝使用教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Python 函數(shù)詳解:從基礎(chǔ)語(yǔ)法到高級(jí)使用技巧

    Python 函數(shù)詳解:從基礎(chǔ)語(yǔ)法到高級(jí)使用技巧

    本文基于實(shí)例代碼,全面講解 Python 函數(shù)的定義、參數(shù)傳遞、變量作用域及類(lèi)型標(biāo)注等知識(shí)點(diǎn),幫助初學(xué)者快速掌握函數(shù)的使用技巧,感興趣的朋友跟隨小編一起學(xué)習(xí)吧
    2025-08-08
  • python實(shí)現(xiàn)換位加密算法的示例

    python實(shí)現(xiàn)換位加密算法的示例

    今天小編就為大家分享一篇python實(shí)現(xiàn)換位加密算法的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • python編寫(xiě)猜數(shù)字小游戲

    python編寫(xiě)猜數(shù)字小游戲

    這篇文章主要為大家詳細(xì)介紹了python編寫(xiě)猜數(shù)字小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • Python如何進(jìn)行時(shí)間處理

    Python如何進(jìn)行時(shí)間處理

    這篇文章主要介紹了Python如何進(jìn)行時(shí)間處理,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-08-08
  • python 多線程將大文件分開(kāi)下載后在合并的實(shí)例

    python 多線程將大文件分開(kāi)下載后在合并的實(shí)例

    今天小編就為大家分享一篇python 多線程將大文件分開(kāi)下載后在合并的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • 人臉識(shí)別實(shí)戰(zhàn)之Opencv+SVM實(shí)現(xiàn)人臉識(shí)別

    人臉識(shí)別實(shí)戰(zhàn)之Opencv+SVM實(shí)現(xiàn)人臉識(shí)別

    這篇文章主要介紹了通過(guò)Opencv+SVM實(shí)現(xiàn)人臉識(shí)別功能,文中的示例代碼介紹詳細(xì),對(duì)于我們學(xué)習(xí)人臉識(shí)別和OpenCV都有一定的幫助,感興趣的小伙伴可以學(xué)習(xí)一下
    2021-12-12
  • Python獲取Redis所有Key以及內(nèi)容的方法

    Python獲取Redis所有Key以及內(nèi)容的方法

    今天小編就為大家分享一篇Python獲取Redis所有Key以及內(nèi)容的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • python3往mysql插入二進(jìn)制圖片出現(xiàn)1064錯(cuò)誤

    python3往mysql插入二進(jìn)制圖片出現(xiàn)1064錯(cuò)誤

    這篇文章主要介紹了python3往mysql插入二進(jìn)制圖片出現(xiàn)1064錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 利用Python展示文件下載進(jìn)度條

    利用Python展示文件下載進(jìn)度條

    這篇文章主要介紹了Python展示文件下載進(jìn)度條,requests庫(kù)相信大家都用過(guò),做接口測(cè)試少不了它。其實(shí)我們平時(shí)下載文件,也可以用requests做到的,通過(guò)一些地址,下面我們就來(lái)看看具體是什么樣的地址及詳細(xì)內(nèi)容,需要的朋友可以參考一下
    2021-11-11

最新評(píng)論

宁津县| 莫力| 大洼县| 宣威市| 陵川县| 五华县| 阜城县| 佳木斯市| 巴林左旗| 昌平区| 噶尔县| 西盟| 比如县| 江华| 綦江县| 南部县| 泰顺县| 遂昌县| 兴安盟| 石渠县| 昌乐县| 廉江市| 怀宁县| 千阳县| 随州市| 金坛市| 宁夏| 铜鼓县| 白水县| 来安县| 五指山市| 扎赉特旗| 郯城县| 炉霍县| 广宗县| 剑河县| 无棣县| 上林县| 长春市| 顺义区| 汪清县|