国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

用Python實現(xiàn)給圖片去黑邊

這篇具有很好參考價值的文章主要介紹了用Python實現(xiàn)給圖片去黑邊。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

圖片去黑邊(只考慮了去水平方向上的黑邊)的核心算法是要找到圖片頂部或頂部的黑邊位置,即兩個縱坐標(biāo)值, 主要用到了canny邊緣計算、
houghlines直線檢測、easyocr識別等算法。

給圖片去黑邊的實現(xiàn)邏輯為:

  1. 先進行canny邊緣計算,再進行houghlines直線檢測,取出圖片的水平邊緣 如果沒有找到水平邊緣,那么不做處理

  2. 對目標(biāo)水平邊緣進行過濾和分類
    過濾邏輯是: 一側(cè)為黑色,另一側(cè)非黑色
    分類邏輯是:
    上邊是黑色,下邊是非黑色的,且位于圖片水平中線以上,作為候選上邊緣;
    上邊是非黑色,下邊是黑色的,,且位于圖片水平中線以下,作為候選下邊緣

  3. 對候選的上下邊緣從外向內(nèi)逐一校驗,校驗標(biāo)準是邊緣之外不應(yīng)存在文字(因為圖片上的文字對于圖片也是有意義的) 也不應(yīng)存在高度超過一定閾值的元素, 從而得出符合條件且最靠內(nèi)側(cè)的上下邊緣
    如果找不到符合條件的上邊緣,那么上邊緣就是0
    如果找不到符合條件的下邊緣,那么下邊緣就是圖片高度-1

  4. 根據(jù)找出的上線邊緣對原圖進行裁剪文章來源地址http://www.zghlxwxcb.cn/news/detail-800207.html

import cv2
import numpy as np
import easyocr


def isPixelBlack(pixel):
    return pixel[0] <= 10 and pixel[1] <= 10 and pixel[2] <= 10


def checkLineIsBlack(img, width, y):
    midX = int((width - 1) / 2)
    pixel = img[y, midX]
    if not isPixelBlack(pixel):
        return False

    for x in range(1, midX + 1):
        if midX - x >= 0:
            leftPixel = img[y, midX - x]
            if not isPixelBlack(leftPixel):
                return False

        if midX + x < width:
            rightPixel = img[y, midX + x]
            if not isPixelBlack(rightPixel):
                return False

    return True


def computeBlackPixelNum(img, fromY, toY, x):
    totalNum = 0
    for y in range(fromY, toY):
        curPixel = img[y, x]
        if isPixelBlack(curPixel):
            totalNum += 1
    return totalNum


# 對于接近頂部或底部的邊緣忽略;對于中線附近的邊緣也忽略;
def isLevelLineNeedIgnore(height, y):
    if y <= 50 or height - 1 - y <= 50:
        return True

    # 判斷y是否介于3/8 到 5/8 的高度之間
    midZoneStart = int(0.4 * height)
    midZoneEnd = int(0.6 * height)

    if y >= midZoneStart and y <= midZoneEnd:
        return True

    return False


# 將寬度的1/6視作最小線段長度
def getMinLineLength(width):
    return int(width / 10)


def computeValidFlag(valid_flag_list, left, right):
    sum = 0
    for index in range(left, right):
        if valid_flag_list[index] > 0:
            sum += 1
    if sum <= 5:
        return 0
    return sum


# 計算水平線的邊緣類型: 0=無效   1=潛在的上邊緣   2=潛在的下邊緣  3 潛在的邊緣
def checkEdgeType(valid_flag_list, y, height, init):
    midY = int(height / 2)

    aboveFlag = computeValidFlag(valid_flag_list, max(0, y - 10 - init), y - 10)
    belowFlag = computeValidFlag(valid_flag_list, y + 10, min(y + 10 + init, height - 1))

    if aboveFlag > 0 and belowFlag > 0:
        return 0
    elif aboveFlag > 0 and belowFlag == 0 and y > midY:
        return 2
    elif aboveFlag == 0 and belowFlag > 0 and y < midY:
        return 1
    elif aboveFlag == 0 and belowFlag == 0:
        return 3
    return 0


# 挑選合適的上邊緣
def pickOutFinalTopY(img, height, width, valid_topY_array, valid_flag_list, reader):
    bestTopY = 0

    matchedTopY = []
    otherTopY = []
    for currentY in valid_topY_array:
        validFlagNum = computeValidFlag(valid_flag_list, 0, currentY - 2)
        if validFlagNum <= 20:
            matchedTopY.append(currentY)
        else:
            otherTopY.append(currentY)

    if len(otherTopY) == 0:
        return matchedTopY[0]
    else:
        matchedTopY.sort()
        if len(matchedTopY) > 0:
            bestTopY = matchedTopY[len(matchedTopY) - 1]
        # 將topY列表升序排列, 逐一驗證是否符合條件
        valid_topY_array.sort()
        midX = int(width / 2)
        for candidateY in valid_topY_array:
            if candidateY < bestTopY:
                continue

            sumFlag = computeValidFlag(valid_flag_list, 0, candidateY)
            if sumFlag > 100:
                break

            sumBlack = computeBlackPixelNum(img, 0, candidateY, midX)
            if sumBlack > 100:
                break

            # ocr讀取 (0,candidateY) 范圍內(nèi)的子圖, 判斷是否包含有文字
            # 如果包含了文字,那么就不符合條件
            roi = img[0:candidateY, 0:width]
            result = reader.readtext(roi)
            if len(result) > 0:
                break

            bestTopY = candidateY

    return bestTopY


def pickOutFinalEndY(img, height, width, valid_endY_array, valid_flag_list, reader):
    bestEndY = height - 1

    matchedEndY = []
    otherEndY = []
    for currentY in valid_endY_array:
        validFlagNum = computeValidFlag(valid_flag_list, currentY + 2, height)
        if validFlagNum <= 20:
            matchedEndY.append(currentY)
        else:
            otherEndY.append(currentY)

    if len(otherEndY) == 0:
        return matchedEndY[0]
    else:
        matchedEndY.sort(reverse=True)
        if len(matchedEndY) > 0:
            bestEndY = matchedEndY[0]

        # 將endY列表降序排列, 逐一驗證是否符合條件
        valid_endY_array.sort(reverse=True)
        midX = int(width / 2)
        for candidateY in valid_endY_array:
            if candidateY > bestEndY:
                continue

            sum = computeValidFlag(valid_flag_list, candidateY, height)
            if sum > 100:
                break

            sumBlack = computeBlackPixelNum(img, candidateY, height, midX)
            if sumBlack > 100:
                break

            # ocr讀取 (candidateY,height) 范圍內(nèi)的子圖, 判斷是否包含有文字
            # 如果包含了文字,那么就不符合條件
            roi = img[candidateY:height, 0:width]
            result = reader.readtext(roi)
            if len(result) > 0:
                break

            bestEndY = candidateY

    return bestEndY


def computeTopAndEnd(img, height, width, valid_flag_list, level_lines, reader):
    # 1.過濾出有效的邊緣
    valid_topY_array = []
    valid_endY_array = []

    midY = int(height / 2)
    for level_line in level_lines:
        x1, y, x2, y2 = level_line[0]

        # 臨時劃線
        # cv2.line(img, (0, y), (width - 1, y), (0, 0, 255), 1)

        # 先判斷是否是有效的邊緣,如果是有效的邊緣, 再放入候選集合中
        edgeType = checkEdgeType(valid_flag_list, y, height, 50)
        if edgeType == 0:
            continue
        elif edgeType == 1:
            valid_topY_array.append(y)
        elif edgeType == 2:
            valid_endY_array.append(y)
        elif edgeType == 3:
            if y > midY:
                valid_endY_array.append(y)
            elif y < midY:
                valid_topY_array.append(y)

    if len(valid_topY_array) <= 0 and len(valid_endY_array) <= 0:
        return 0, height - 1

    # 2.判斷有效的邊緣是否可以上邊緣或下邊緣(這個步驟里可能會用到ocr技術(shù))
    finalTopY = 0
    finalEndY = height - 1
    if len(valid_topY_array) > 0:
        finalTopY = pickOutFinalTopY(img, height, width, valid_topY_array, valid_flag_list, reader)

    if len(valid_endY_array) > 0:
        finalEndY = pickOutFinalEndY(img, height, width, valid_endY_array, valid_flag_list, reader)

    # 3.返回上下黑邊縱坐標(biāo)
    return finalTopY, finalEndY


# 對于無邊緣的縱坐標(biāo), 重新計算該縱坐標(biāo)上是否存在非黑像素
def recomputeValidFlagList(img, height, width, valid_flag_list):
    for y in range(0, height):
        if valid_flag_list[y] == 0:
            lineBlackFlag = checkLineIsBlack(img, width, y)
            if not lineBlackFlag:
                valid_flag_list[y] = 1


def recognizeImageValidZone(imagePath, reader):
    # 讀取圖片
    img = cv2.imread(imagePath)
    # 獲取圖像尺寸
    height, width = img.shape[:2]

    edges = cv2.Canny(img, 100, 200)
    lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=getMinLineLength(width), maxLineGap=10)

    if lines is None:
        print(imagePath + "不存在直線")
        return 0, height - 1

    levelLines = []
    for line in lines:
        x1, y1, x2, y2 = line[0]
        if y1 != y2:
            continue

        if isLevelLineNeedIgnore(height, y1):
            continue
        # print(f"水平直線===================={y1}")
        # cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
        levelLines.append(line)

    if len(levelLines) == 0:
        print(imagePath + "-----不存在水平直線")
        return 0, height - 1

    # 計算標(biāo)識數(shù)組,用于標(biāo)識各行是否存在非黑像素
    valid_flag_list = [0 for _ in range(height)]
    # 遍歷邊緣檢測后的圖像,找到邊緣像素的坐標(biāo)
    for y in range(edges.shape[0]):
        for x in range(edges.shape[1]):
            if edges[y][x] != 0:  # 如果當(dāng)前像素不是背景(即邊緣)
                valid_flag_list[y] = 1
                break

    recomputeValidFlagList(img, height, width, valid_flag_list)

    return computeTopAndEnd(img, height, width, valid_flag_list, levelLines, reader)


def doDropForImage(srcDir, srcFile, targetDir, reader):
    # 讀取圖片
    img = cv2.imread(srcDir + srcFile)
    # 獲取圖像尺寸
    height, width = img.shape[:2]
    # 獲取起止的縱坐標(biāo)
    startY, overY = recognizeImageValidZone(srcDir + srcFile, reader)
    crop_img = img[startY:overY + 1, 0:width]
    cv2.imwrite(targetDir + srcFile + "_dealed.jpg", crop_img)


def preDropForImage(srcDir, srcFile, targetDir, reader):
    # 讀取圖片
    img = cv2.imread(srcDir + srcFile)
    # 獲取圖像尺寸
    height, width = img.shape[:2]
    # 獲取起止的縱坐標(biāo)
    startY, overY = recognizeImageValidZone(srcDir + srcFile, reader)
    # 標(biāo)記一下圖片邊緣
    if startY != 0:
        cv2.line(img, (0, startY), (width - 1, startY), (0, 255, 0), 2)
    if overY != height - 1:
        cv2.line(img, (0, overY), (width - 1, overY), (0, 255, 0), 2)

    if startY == 0 and overY == height - 1:
        cv2.imwrite(targetDir + 'unchanged/' + srcFile + "_dealed.jpg", img)
    else:
        cv2.imwrite(targetDir + 'changed/' + srcFile, img)


reader = easyocr.Reader(['ch_sim', 'en'], gpu=False)
preDropForImage('E:/black/sample_images_black/', "1.jpg", 'E:/black/success_dealed/', reader)



到了這里,關(guān)于用Python實現(xiàn)給圖片去黑邊的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Python怎么將pdf轉(zhuǎn)為圖片?Python如何實現(xiàn)pdf文件轉(zhuǎn)圖片

    而pdf則是用來保存一些內(nèi)容已經(jīng)確定好的數(shù)據(jù),因為pdf是無法直接修改內(nèi)容的,所以也會經(jīng)常將pdf轉(zhuǎn)為圖片來保存。本文就將會來介紹一下pdf轉(zhuǎn)圖片的方法,往下看看吧。 1.pdf轉(zhuǎn)圖片的話主要實現(xiàn)所需要的模塊叫做PyMuPDF,它就是用來操作pdf文件的,通過pip工具下載安裝即可。

    2024年02月11日
    瀏覽(27)
  • Python實現(xiàn):圖片疊加與融合

    Python實現(xiàn):圖片疊加與融合 在圖像處理和計算機視覺中,圖像的疊加和融合是一項重要的功能。通過疊加和融合不同的圖像,我們可以實現(xiàn)許多有趣的應(yīng)用,例如將兩張圖片疊加成一張,比較兩幅圖片的相似度等等。 Python作為一種高級編程語言,提供了豐富的圖像處理和計

    2024年02月11日
    瀏覽(17)
  • Python實現(xiàn)圖片亮度調(diào)整算法

    Python實現(xiàn)圖片亮度調(diào)整算法 圖片亮度調(diào)整是圖像處理中常用的技術(shù)之一。通過改變圖片的亮度,可以使得圖片更清晰、更具藝術(shù)效果。下面將介紹如何使用Python實現(xiàn)這一功能。 首先,我們需要導(dǎo)入Python中的圖像處理庫PIL: 接下來,我們需要打開一張圖片,并進行亮度調(diào)整。

    2024年02月08日
    瀏覽(15)
  • python實現(xiàn)圖片轉(zhuǎn)視頻功能

    PyCharm ,將會帶來全新的寫作體驗; 安裝OpenCV庫

    2024年02月12日
    瀏覽(16)
  • Python實現(xiàn)圖片二值化

    Python實現(xiàn)圖片二值化

    圖像二值化就是將圖像上的像素點的“灰度值”設(shè)置為[0, 0, 0]或[255, 255, 255],即要么純黑,要么純白。 通過二值化,能更好地分析物體的形狀和輪廓。 二值化的實現(xiàn)一般有: 全局閾值法、自適應(yīng)閾值法、OTSU二值化等 (1)全局閾值法 就是選定一個全局閾值,大于這個值的色

    2024年02月11日
    瀏覽(17)
  • Window安裝Python和開發(fā)Pycharm

    Window安裝Python和開發(fā)Pycharm

    準備: ?1:安裝Python環(huán)境? ??https://www.python.org/downloads/windows/ 2:? 下載Pycharm? ?https://www.jetbrains.com/pycharm/download/other.html?

    2024年01月22日
    瀏覽(26)
  • 如何在Python中獲取圖片分辨率?——Python實現(xiàn)獲取圖片分辨率的代碼及詳解。

    如何在Python中獲取圖片分辨率?——Python實現(xiàn)獲取圖片分辨率的代碼及詳解。 在進行圖片處理或者圖片分析的時候,獲取圖片的分辨率信息是必不可少的。Python提供了許多庫可以方便地獲取圖片的分辨率信息。在本文中,我們將詳細介紹如何使用Python實現(xiàn)獲取圖片分辨率的功

    2024年02月07日
    瀏覽(44)
  • 用python實現(xiàn)文本/圖片生成視頻

    使用Python來生成視頻通常涉及到使用一些專門的庫,比如 OpenCV 或者 moviepy。下面是一個簡單的例子,使用OpenCV和PIL(Python Imaging Library)來創(chuàng)建一個視頻。 python復(fù)制代碼 import cv2 import numpy as np from PIL import Image import os # 圖片路徑列表 image_list = [\\\'img1.jpg\\\', \\\'img2.jpg\\\', \\\'img3.jpg\\\'] # 視頻

    2024年01月17日
    瀏覽(16)
  • 人工智能——“kmeans實現(xiàn)圖片分割”(Python實現(xiàn))

    人工智能——“kmeans實現(xiàn)圖片分割”(Python實現(xiàn))

    (2)邊緣分割:對圖像邊緣進行檢測,即檢測圖像中灰度值發(fā)生跳變的地方,則為一片 區(qū)域的邊緣。 (3)直方圖法:對圖像的顏色建立直方圖,而直方圖的波峰波谷能夠表示一塊區(qū)域的顏 色值的范圍,來達到分割的目的。 (4)特定理論:基于 聚類分析 、小波變換等理論完成圖像

    2024年04月17日
    瀏覽(45)
  • 【Python爬蟲開發(fā)實戰(zhàn)①】使用urllib以及XPath爬取可愛小貓圖片

    【Python爬蟲開發(fā)實戰(zhàn)①】使用urllib以及XPath爬取可愛小貓圖片

    個人主頁 :為夢而生~ 關(guān)注我一起學(xué)習(xí)吧! 專欄 :python網(wǎng)絡(luò)爬蟲從基礎(chǔ)到實戰(zhàn) 歡迎訂閱!后面的內(nèi)容會越來越有意思~ 往期推薦 : 【Python爬蟲開發(fā)基礎(chǔ)⑦】urllib庫的基本使用 【Python爬蟲開發(fā)基礎(chǔ)⑧】XPath庫及其基本用法 我們在之前已經(jīng)有8篇文章講述基礎(chǔ)知識了,下面我們

    2024年02月11日
    瀏覽(168)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包