天天日夜夜添_精品国产99久久久久久人裸体 _成人app在线观看_日韩色网站

新聞資訊

    C#11 添加了文件作用域類(lèi)型功能:一個(gè)新的 file 修飾符,可以應(yīng)用于任何類(lèi)型定義以限制其只能在當(dāng)前文件中使用。這樣,我們可以在一個(gè)項(xiàng)目中擁有多個(gè)同名的類(lèi)。

    通過(guò)下面的項(xiàng)目顯示,該項(xiàng)目包含兩個(gè)名為Answer的類(lèi)。

    文件File1.cs中

    namespace ConsoleApp11
    {
        file static class Answer
        {
            internal static string GetFileScopeScret() => "File1.cs";
        }
    
    
        static class InternalClassFromFile1
        {
            internal static string GetString() => Answer.GetFileScopeScret();
        }
    }


    文件File2.cs中

    namespace ConsoleApp11
    {
        file static class Answer
        {
            internal static string GetFileScopeScret() => "File2.cs";
        }
    
    
        static class InternalClassFromFile2
        {
            internal static string GetString() => Answer.GetFileScopeScret();
        }
    }


    調(diào)用這兩個(gè)方法,可以正常輸出

    static void Main(string[] args)
    {
        Console.WriteLine(InternalClassFromFile1.GetString());
        Console.WriteLine(InternalClassFromFile2.GetString());
    }



    這里有幾點(diǎn)說(shuō)明:

    • 可以在其源文件之外間接訪問(wèn)帶有file修飾符的類(lèi)型。在上面的程序中,我們依賴(lài)這些類(lèi),并從 InternalClassFromFile1 與 InternalClassFromFile2中訪問(wèn)。
    • file類(lèi)也可以接口在其源文件之外間接使用,演示如下


    修改File.cs中代碼

    namespace ConsoleApp11
    {
        file class Answer : IAnswer
        {
            public string GetFileScopeSecret() => "File1.cs";
        }
        internal interface IAnswer
        {
            string GetFileScopeSecret();
        }
        static class InternalClassFromFile1
        {
            internal static IAnswer GetAnswer() => new Answer();
        }
    }


    調(diào)用方法,即可正常輸出

    static void Main(string[] args)
    {
        Console.WriteLine(InternalClassFromFile1.GetAnswer().GetFileScopeSecret());
    }


    • 任何類(lèi)型的類(lèi)型都可以用file修飾符標(biāo)記:class, interface , record , struct, enum, delegate.
    • file不能與其他修飾符(如internal or public)一起使用。
    • 只要所有類(lèi)型定義屬于同一個(gè)文件,就可以使用分部類(lèi):
    namespace ConsoleApp1 {
       file static partial class Answer {
          internal static string GetFileScopeSecret()
             => "Answer from File1.cs";
       }
       file static partial class Answer {
          internal static string AnotherGetFileScopeSecret()
             => "Another Answer from File1.cs";
       }
    }


    • file修飾符不適用于嵌套在父類(lèi)型中的類(lèi)型。它也不適用于方法屬性、事件和字段,但語(yǔ)言設(shè)計(jì)說(shuō)明解釋說(shuō):“為非類(lèi)型文件范圍的成員留出設(shè)計(jì)空間,以便以后出現(xiàn)。”
    • 在一個(gè)項(xiàng)目中,可以有一個(gè)internal級(jí)別類(lèi),同時(shí)可以擁有一個(gè)或多個(gè)file級(jí)別的同名類(lèi)。 唯一的缺點(diǎn)是文件類(lèi)不能在公共類(lèi)中使用。

    讓我們強(qiáng)調(diào)一下,namespace仍然是避免類(lèi)型名稱(chēng)沖突的首選方法。

    我們?cè)诰W(wǎng)上瀏覽網(wǎng)頁(yè)或注冊(cè)賬號(hào)時(shí),會(huì)經(jīng)常遇到驗(yàn)證碼(CAPTCHA),如下圖:
    
     本文將具體介紹如何利用Python的圖像處理模塊pillow和OCR模塊pytesseract來(lái)識(shí)別上述驗(yàn)證碼(數(shù)字加字母)。
    

    我們識(shí)別上述驗(yàn)證碼的算法過(guò)程如下:

    1. 將原圖像進(jìn)行灰度處理,轉(zhuǎn)化為灰度圖像;
    2. 獲取圖片中像素點(diǎn)數(shù)量最多的像素(此為圖片背景),將該像素作為閾值進(jìn)行二值化處理,將灰度圖像轉(zhuǎn)化為黑白圖像(用來(lái)提高識(shí)別的準(zhǔn)確率);
    3. 去掉黑白圖像中的噪聲,噪聲定義為:以該點(diǎn)為中心的九宮格的黑點(diǎn)的數(shù)量小于等于 4;
    4. 利用 pytesseract 模塊識(shí)別,去掉識(shí)別結(jié)果中的特殊字符,獲得識(shí)別結(jié)果。

    我們的圖片如下(共 66 張圖片):

    完整的 Python 代碼如下:

    import os
    import pytesseract
    from PIL import Image
    from collections import defaultdict
    # tesseract.exe所在的文件路徑
    pytesseract.pytesseract.tesseract_cmd = 'C://Program Files (x86)/Tesseract-OCR/tesseract.exe'
    # 獲取圖片中像素點(diǎn)數(shù)量最多的像素
    def get_threshold(image):
     pixel_dict = defaultdict(int)
     # 像素及該像素出現(xiàn)次數(shù)的字典
     rows, cols = image.size
     for i in range(rows):
     for j in range(cols):
     pixel = image.getpixel((i, j))
     pixel_dict[pixel] += 1
     count_max = max(pixel_dict.values()) # 獲取像素出現(xiàn)出多的次數(shù)
     pixel_dict_reverse = {v:k for k,v in pixel_dict.items()}
     threshold = pixel_dict_reverse[count_max] # 獲取出現(xiàn)次數(shù)最多的像素點(diǎn)
     return threshold
    # 按照閾值進(jìn)行二值化處理
    # threshold: 像素閾值
    def get_bin_table(threshold):
     # 獲取灰度轉(zhuǎn)二值的映射table
     table = []
     for i in range(256):
     rate = 0.1 # 在threshold的適當(dāng)范圍內(nèi)進(jìn)行處理
     if threshold*(1-rate)<= i <= threshold*(1+rate):
     table.append(1)
     else:
     table.append(0)
     return table
    # 去掉二值化處理后的圖片中的噪聲點(diǎn)
    def cut_noise(image):
     rows, cols = image.size # 圖片的寬度和高度
     change_pos = [] # 記錄噪聲點(diǎn)位置
     # 遍歷圖片中的每個(gè)點(diǎn),除掉邊緣
     for i in range(1, rows-1):
     for j in range(1, cols-1):
     # pixel_set用來(lái)記錄該店附近的黑色像素的數(shù)量
     pixel_set = []
     # 取該點(diǎn)的鄰域?yàn)橐栽擖c(diǎn)為中心的九宮格
     for m in range(i-1, i+2):
     for n in range(j-1, j+2):
     if image.getpixel((m, n)) != 1: # 1為白色,0位黑色
     pixel_set.append(image.getpixel((m, n)))
     # 如果該位置的九宮內(nèi)的黑色數(shù)量小于等于4,則判斷為噪聲
     if len(pixel_set) <= 4:
     change_pos.append((i,j))
     # 對(duì)相應(yīng)位置進(jìn)行像素修改,將噪聲處的像素置為1(白色)
     for pos in change_pos:
     image.putpixel(pos, 1)
     return image # 返回修改后的圖片
    # 識(shí)別圖片中的數(shù)字加字母
    # 傳入?yún)?shù)為圖片路徑,返回結(jié)果為:識(shí)別結(jié)果
    def OCR_lmj(img_path):
     image = Image.open(img_path) # 打開(kāi)圖片文件
     imgry = image.convert('L') # 轉(zhuǎn)化為灰度圖
     # 獲取圖片中的出現(xiàn)次數(shù)最多的像素,即為該圖片的背景
     max_pixel = get_threshold(imgry)
     # 將圖片進(jìn)行二值化處理
     table = get_bin_table(threshold=max_pixel)
     out = imgry.point(table, '1')
     # 去掉圖片中的噪聲(孤立點(diǎn))
     out = cut_noise(out)
     #保存圖片
     # out.save('E://figures/img_gray.jpg')
     # 僅識(shí)別圖片中的數(shù)字
     #text = pytesseract.image_to_string(out, config='digits')
     # 識(shí)別圖片中的數(shù)字和字母
     text = pytesseract.image_to_string(out)
     # 去掉識(shí)別結(jié)果中的特殊字符
     exclude_char_list = ' .:\\|\'\"?![],()~@#$%^&*_+-={};<>/¥'
     text = ''.join([x for x in text if x not in exclude_char_list])
     #print(text)
     return text
    def main():
     
     # 識(shí)別指定文件目錄下的圖片
     # 圖片存放目錄figures
     dir = 'E://figures'
     correct_count = 0 # 圖片總數(shù)
     total_count = 0 # 識(shí)別正確的圖片數(shù)量
     # 遍歷figures下的png,jpg文件
     for file in os.listdir(dir):
     if file.endswith('.png') or file.endswith('.jpg'):
     # print(file)
     image_path = '%s/%s'%(dir,file) # 圖片路徑
     answer = file.split('.')[0] # 圖片名稱(chēng),即圖片中的正確文字
     recognizition = OCR_lmj(image_path) # 圖片識(shí)別的文字結(jié)果
     print((answer, recognizition))
     if recognizition == answer: # 如果識(shí)別結(jié)果正確,則total_count加1
     correct_count += 1
     total_count += 1
     print('Total count: %d, correct: %d.'%(total_count, correct_count))
     '''
     # 單張圖片識(shí)別
     image_path = 'E://figures/code (1).jpg'
     OCR_lmj(image_path)
     '''
    main()
    

    運(yùn)行結(jié)果如下:

    ('101659', '101659')

    ('111073', '111073')

    ('114510', '114510')

    ('118235', '118235')

    ('124677', '124677')

    ('147291', '147291')

    ('169147', '169147')

    ('185302', '185302')

    ('23YB', '23YB')

    ('262051', '262051')

    ('2HED', '2MED')

    ('315386', '315386')

    ('3D7K', '3D7K')

    ('3DYH', '3DYH')

    ('3QG8', '30G8')

    ('3XNR', 'EXNR')

    ('44G5', '44G5')

    ('470259', '470259')

    ('515413', '515413')

    ('522351', '522351')

    ('539824', '539824')

    ('5CVL', 'SCVL')

    ('642689', '642689')

    ('671991', '671991')

    ('672838', '672838')

    ('6F5Y', '6F5Y')

    ('6USB', 'GUSB')

    ('703167', '703167')

    ('765120', '765120')

    ('779931', '779931')

    ('8UEF', '8SUEF')

    ('905857', '905857')

    ('9H4H', '9H4H')

    ('9SK1', 'OSK1')

    ('BDP4', 'BDP4')

    ('DXV3', 'DXV3')

    ('E78Y', 'E78Y')

    ('EAHR', 'EAHR')

    ('F585', 'Fss§')

    ('FBV8', 'FBV8')

    ('FJKK', 'FJKK')

    ('GXKQ', 'GXKQ')

    ('H7Y9', 'H7Y9')

    ('J4LJ', 'J4LJ')

    ('J8YH', 'J8YH')

    ('JCDL', 'JCDL')

    ('JTX2', 'JTX2')

    ('JYLH', 'JYLH')

    ('KFYA', 'KFYA')

    ('L3VZ', 'L3VZ')

    ('LCGV', 'LCGV')

    ('LKEK', 'LKEK')

    ('N3FJ', 'N3FJ')

    ('PJZN', 'PJZN')

    ('PNDQ', 'PNDQ')

    ('Q7HP', 'Q7HP')

    ('QSHU', 'QSHU')

    ('R1RN', 'RLRN')

    ('RPNX', 'RPNX')

    ('TUKG', 'TUKG')

    ('U9G3', 'U9G3')

    ('UZAH', 'UZAH')

    ('V6P9', 'very')

    ('Y18D', '18D')

    ('Y237', 'Y237')

    ('ZZT5', '2215')

    Total count: 66, correct: 54.

    我們可以看到圖片識(shí)別的正確率為 80% 以上,其中數(shù)字類(lèi)圖片的識(shí)別正確率為 100%.

    我們可以在圖片識(shí)別方面的算法再加改進(jìn),以提高圖片識(shí)別的正確率。當(dāng)然,以上算法并不是對(duì)所有驗(yàn)證碼都適用,不同的驗(yàn)證碼需要用不同的圖片處理算法。

    附錄:

    1.Tesseract 的安裝與使用

    Tesseract 的 Windows 安裝包下載地址為: http://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-4.00.00dev.exe ,下載后雙擊直接安裝即可。安裝完后,需要將 Tesseract 添加到系統(tǒng)變量中。在 CMD 中輸入 tesseract -v, 如顯示以下界面,則表示 Tesseract 安裝完成且添加到系統(tǒng)變量中。

    2.pytesseract

    pytesseract 是 Tesseract 關(guān)于 Python 的接口,可以使用 pip install pytesseract 安裝。安裝完后,就可以使用 Python 調(diào)用 Tesseract 了,不過(guò),你還需要一個(gè) Python 的圖片處理模塊,可以安裝 pillow.

    輸入以下代碼,可以實(shí)現(xiàn)同上述 Tesseract 命令一樣的效果:

網(wǎng)站首頁(yè)   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有