

<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>OpenCV &#8211; Max的程式語言筆記</title>
	<atom:link href="https://stackoverflow.max-everyday.com/tag/opencv/feed/" rel="self" type="application/rss+xml" />
	<link>https://stackoverflow.max-everyday.com</link>
	<description>我要當一個豬頭，快樂過每一天</description>
	<lastBuildDate>Sat, 17 Jul 2021 10:56:11 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://stackoverflow.max-everyday.com/wp-content/uploads/2017/02/max-stackoverflow-256.png</url>
	<title>OpenCV &#8211; Max的程式語言筆記</title>
	<link>https://stackoverflow.max-everyday.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>[Python] OpenCV 彩色轉灰階(RGB to Gray)</title>
		<link>https://stackoverflow.max-everyday.com/2021/07/python-opencv-rgb-to-gray/</link>
					<comments>https://stackoverflow.max-everyday.com/2021/07/python-opencv-rgb-to-gray/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Sat, 17 Jul 2021 10:56:09 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=3883</guid>

					<description><![CDATA[第一種方式: import cv2 image ...]]></description>
										<content:encoded><![CDATA[
<p>第一種方式:</p>



<p>import cv2</p>



<p>image = cv2.imread(&#8216;test.jpg&#8217;) #讀取影像</p>



<p>image_g = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #透過轉換函式轉為灰階影像</p>



<p>cv2.imwrite(&#8216;test_g.jpg&#8217;, image_g) #儲存影像</p>



<p>第二種方式:</p>



<p>import cv2</p>



<p>image_g = cv2.imread(&#8216;test.jpg&#8217;, 0) #直接以灰階方式讀取影像</p>



<p>cv2.imwrite(&#8216;test_g.jpg&#8217;, image_g) #儲存影像</p>



<pre class="wp-block-code"><code>img = cv2.imread('gray.jpg',0)
</code></pre>



<p><strong>0</strong>&nbsp;for gray and&nbsp;<strong>1</strong>&nbsp;for color</p>



<hr class="wp-block-separator"/>



<p><code>cv2.imread</code> load an image with three channels unless <code>CV_LOAD_IMAGE_GRAYSCALE</code> is set.</p>



<pre class="wp-block-code"><code>>>> import cv2
>>> image = cv2.imread('foo.jpg')
>>> print image.shape
 (184, 300, 3)
>>> gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
>>> print gray_image.shape 
 (184, 300)
>>> cv2.imwrite('gray.jpg', gray_image)
</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2021/07/python-opencv-rgb-to-gray/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>opencv python 影像模糊與反鋸齒處理</title>
		<link>https://stackoverflow.max-everyday.com/2021/07/opencv-python-image-blur-anti-aliasing/</link>
					<comments>https://stackoverflow.max-everyday.com/2021/07/opencv-python-image-blur-anti-aliasing/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 16 Jul 2021 09:52:48 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=3869</guid>

					<description><![CDATA[很實用的技能，建議學起來。一行指令就搞定了。好強...]]></description>
										<content:encoded><![CDATA[
<p>很實用的技能，建議學起來。一行指令就搞定了。好強的 OpenCV</p>



<p>如果還沒有安裝opencv 請服用下面的指令：</p>



<pre class="wp-block-preformatted">python3 -m pip install opencv-python
</pre>



<hr class="wp-block-separator"/>



<p>影象平滑技術如高斯模糊，Median模糊等，模糊真的很好用，因為模糊捨棄了「細節」，再結合二值化（Image Thresholding），就可以讓原有的資訊變的更圓潤和飽滿，可以做出反鋸齒(Anti-aliasing)的效果。</p>



<p>OpenCV 的平滑模糊化技術：</p>



<ul class="wp-block-list"><li><code>平均濾波 Averaging</code>：使用 opencv 的 cv2.blur 或 cv2.boxFilter</li><li><code>高斯濾波 Gaussian Filtering</code>：使用 opencv 的 cv2.GaussianBlur</li><li><code>中值濾波 Median Filtering</code>：使用 opencv 的 cv2.medianBlur</li><li><code>雙邊濾波 Bilateral Filtering</code>：使用 opencv 的 cv2.bilateralFilter</li></ul>



<p>使用範例：</p>



<pre class="wp-block-preformatted">import cv2
import numpy as np
img = cv2.imread('opencv-logo-white.png')
blur = cv2.blur(img,(5,5))</pre>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">二值化</h2>



<p>影像二值化簡單的方法，如果像素值pixel大於門檻值threshold，就指定一個新數值(例如白色)，否則就指定另一個新數值(例如黑色)，<br>這邊使用 opencv 的 cv2.threshold，第一個參數來源需要是灰階影像，第二個參數是用來對像素值進行分類的門檻值，第三個參數為最大灰階值，第四個參數為二值化的類型如下所示：<br><code>cv2.THRESH_BINARY</code>：Threshold Binary，即二值化，將大於門檻值的灰階值設為最大灰階值，小於門檻值的值設為0。<br><code>cv2.THRESH_BINARY_INV</code>：Threshold Binary, Inverted，將大於門檻值的灰階值設為0，其他值設為最大灰階值。<br><code>cv2.THRESH_TRUNC</code>：Truncate，將大於門檻值的灰階值設為門檻值，小於門檻值的值保持不變。<br><code>cv2.THRESH_TOZERO</code>：Threshold to Zero，將小於門檻值的灰階值設為0，大於門檻值的值保持不變。<br><code>cv2.THRESH_TOZERO_INV</code>：Threshold to Zero, Inverted，將大於門檻值的灰階值設為0，小於門檻值的值保持不變。</p>



<p>使用範例：</p>



<pre class="wp-block-preformatted">import cv2
import numpy as np
img = cv2.imread('your-image.png', 0)
ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)</pre>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">執行結果</h2>



<p><strong>1:使用 Blur + threshold</strong></p>



<p>右邊是原圖，右邊是套用效果後。</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="506" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-B-1024x506.jpg?v=1626429481" alt="" class="wp-image-3875" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-B-1024x506.jpg?v=1626429481 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-B-600x296.jpg?v=1626429481 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-B-768x379.jpg?v=1626429481 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-B.jpg?v=1626429481 1478w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>2:使用 GaussianBlur + threshold</strong></p>



<p>右邊是原圖，右邊是套用效果後。</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="506" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-C-1024x506.jpg?v=1626429486" alt="" class="wp-image-3876" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-C-1024x506.jpg?v=1626429486 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-C-600x296.jpg?v=1626429486 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-C-768x379.jpg?v=1626429486 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-C.jpg?v=1626429486 1478w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>3:使用 medianBlur + threshold</strong></p>



<p>右邊是原圖，右邊是套用效果後。</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="506" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-D-1024x506.jpg?v=1626429491" alt="" class="wp-image-3877" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-D-1024x506.jpg?v=1626429491 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-D-600x296.jpg?v=1626429491 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-D-768x379.jpg?v=1626429491 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/A-side-D.jpg?v=1626429491 1478w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>心得，使用起來差異不會很大，但Blur 可以調的模糊程度會較高，較大的筆觸會造成較嚴重的暈染效果，還有筆畫相連。先降噪，blur ，再降噪，再取二值化，這些步驟重覆並交叉套用，效果也很好！</p>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">相關文章</h2>



<p>Smoothing Images<br><a href="https://docs.opencv.org/4.5.2/d4/d13/tutorial_py_filtering.html">https://docs.opencv.org/4.5.2/d4/d13/tutorial_py_filtering.html</a></p>



<p>影像平滑模糊化 blur<br><a href="https://shengyu7697.github.io/python-opencv-blur/">https://shengyu7697.github.io/python-opencv-blur/</a></p>



<p>影像二值化 Image Thresholding<br><a href="https://shengyu7697.github.io/python-opencv-threshold/">https://shengyu7697.github.io/python-opencv-threshold/</a></p>



<p>opencv python 影像去噪<br><a href="https://stackoverflow.max-everyday.com/2021/07/opencv-python-image-denoise/">https://stackoverflow.max-everyday.com/2021/07/opencv-python-image-denoise/</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2021/07/opencv-python-image-blur-anti-aliasing/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>opencv python 影像去噪</title>
		<link>https://stackoverflow.max-everyday.com/2021/07/opencv-python-image-denoise/</link>
					<comments>https://stackoverflow.max-everyday.com/2021/07/opencv-python-image-denoise/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 16 Jul 2021 09:37:55 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=3867</guid>

					<description><![CDATA[很實用的技能，建議學起來。一行指令就搞定了。好強...]]></description>
										<content:encoded><![CDATA[
<p>很實用的技能，建議學起來。一行指令就搞定了。好強的 OpenCV</p>



<p>如果還沒有安裝opencv 請服用下面的指令：</p>



<pre class="wp-block-preformatted">python3 -m pip install opencv-python</pre>



<hr class="wp-block-separator"/>



<p>OpenCV提供了這種技術的四種變體。</p>



<ul class="wp-block-list"><li>cv2.fastNlMeansDenoising（） &#8211; 使用單個灰度影象</li><li>cv2.fastNlMeansDenoisingColored（） &#8211; 使用彩色影象。</li><li>cv2.fastNlMeansDenoisingMulti（） &#8211; 用於在短時間內捕獲的影象序列（灰度影象）</li><li>cv2.fastNlMeansDenoisingColoredMulti（） &#8211; 與上面相同，但用於彩色影象。</li></ul>



<p>參數：</p>



<ol class="wp-block-list"><li>h：引數決定濾波器強度。較高的h值可以更好地消除噪聲，但也會刪除影象的細節 (10 is ok)</li><li>hForColorComponents：與h相同，但僅適用於彩色影象。 （通常與h相同）</li><li>templateWindowSize：應該是奇數。 （recommended 7）</li><li>searchWindowSize：應該是奇數。 （recommended 21）</li></ol>



<p><code>使用範例：</code></p>



<pre class="wp-block-preformatted">import numpy as np
import cv2 as cv
img = cv.imread('die.png')
dst = cv.fastNlMeansDenoisingColored(img,None,10,10,7,21)</pre>



<p>如上所述，它用於從彩色影象中去除噪聲。 </p>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">相關文章</h2>



<p>Image Denoising<br><a href="https://docs.opencv.org/3.4/d5/d69/tutorial_py_non_local_means.html">https://docs.opencv.org/3.4/d5/d69/tutorial_py_non_local_means.html</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2021/07/opencv-python-image-denoise/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[Python] 圖片降噪</title>
		<link>https://stackoverflow.max-everyday.com/2019/06/python-opencv-denoising/</link>
					<comments>https://stackoverflow.max-everyday.com/2019/06/python-opencv-denoising/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 03 Jun 2019 21:15:13 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[PIL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[selenium]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=2838</guid>

					<description><![CDATA[圖片驗證碼識別的可以分為幾個步驟，一般用 Pil...]]></description>
										<content:encoded><![CDATA[
<p>圖片驗證碼識別的可以分為幾個步驟，一般用 Pillow 庫或 OpenCV 來實現，取得圖片驗證碼文字的處理流程：</p>



<ul class="wp-block-list"><li>1.灰度處理&amp;二值化</li><li>2.降噪<br>所謂降噪就是把不需要的信息通通去除，比如背景，干擾線，干擾像素等等，只留下需要識別的字符，讓圖片變成2進制點陣，方便代入模型訓練。</li><li>3.字符分割</li><li>4.標準化</li><li>5.識別 （OCR）</li></ul>



<p>參考了這部教學影片：<br>[爬蟲實戰] 如何破解高鐵驗證碼 (1) &#8211; 去除圖片噪音點?<br><a href="https://www.youtube.com/watch?v=6HGbKdB4kVY">https://www.youtube.com/watch?v=6HGbKdB4kVY</a></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="[爬蟲實戰] 如何破解高鐵驗證碼 (1) - 去除圖片噪音點?" width="640" height="360" src="https://www.youtube.com/embed/6HGbKdB4kVY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<hr class="wp-block-separator"/>



<p>python 用pip安装 cv2:</p>



<pre class="wp-block-preformatted">pip install opencv-python</pre>



<p>說明：macOS 預設 python2 裡 numpy 的版本 numpy-1.8.0rc1，但 opencv 需要 1.11.1 以上，所以會安裝失敗，顯示：</p>



<pre class="wp-block-preformatted">ERROR: Cannot uninstall 'numpy'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.</pre>



<p>解法：</p>



<p>sudo python -m pip install numpy &#8211;ignore-installed numpy<br>sudo python -m pip install opencv-python</p>



<p>python 用pip安装 matplotlib:</p>



<pre class="wp-block-preformatted">pip install matplotlib</pre>



<p>python 用pip安装 pytesseract:</p>



<pre class="wp-block-preformatted">pip install pytesseract</pre>



<p>Tesseract OCR 安裝方法：<br><a href="https://github.com/tesseract-ocr/tesseract/wiki">https://github.com/tesseract-ocr/tesseract/wiki</a></p>



<hr class="wp-block-separator"/>



<p>透過 selenium 的  element.screenshot() 即可取得驗證碼圖片：<br><a href="https://selenium-python-zh.readthedocs.io/en/latest/api.html?highlight=screenshot#selenium.webdriver.remote.webelement.WebElement.screenshot">https://selenium-python-zh.readthedocs.io/en/latest/api.html?highlight=screenshot#selenium.webdriver.remote.webelement.WebElement.screenshot</a></p>



<p><code><strong>screenshot</strong></code>(<em>filename</em>)Saves a&nbsp;<strong>screenshot</strong>&nbsp;of the current element to a PNG image file. ReturnsFalse if there is any IOError, else returns True. Use full paths in your filename.</p>



<table class="wp-block-table"><tbody><tr><th>Args:</th><td>filename: The full path you wish to save your&nbsp;<strong>screenshot</strong>&nbsp;to. This should end with a&nbsp;.png&nbsp;extension.</td></tr><tr><th>Usage:</th><td>element.<strong>screenshot</strong>(‘/Screenshots/foo.png’)</td></tr></tbody></table>



<hr class="wp-block-separator"/>



<p>Max取得到 screenshot:</p>



<ul class="wp-block-gallery columns-1 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="280" height="90" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2019/06/captcha.png" alt="" data-id="2843" data-link="https://stackoverflow.max-everyday.com/?attachment_id=2843" class="wp-image-2843"/></figure></li></ul>



<p>透過下面的python程式：</p>



<pre class="wp-block-preformatted">from PIL import Image,ImageDraw<br>image = Image.open("captcha.png").convert("L")</pre>



<p>取得convert 為灰階後影像檔：</p>



<ul class="wp-block-gallery columns-1 is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="280" height="90" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2019/06/test1.png" alt="" data-id="2844" data-link="https://stackoverflow.max-everyday.com/?attachment_id=2844" class="wp-image-2844"/></figure></li></ul>



<p>透過下面程式，用來2分化影像：</p>



<pre class="wp-block-preformatted">def binarizing(img,threshold): #input: gray image
     pixdata = img.load()
     w, h = img.size
     for y in range(h):
       for x in range(w):
           if pixdata[x, y] &lt; threshold:
               pixdata[x, y] = 0
           else:
               pixdata[x, y] = 255
     return img</pre>



<ul class="wp-block-gallery columns-1 is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="280" height="90" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2019/06/test2_binarizing.png" alt="" data-id="2845" data-link="https://stackoverflow.max-everyday.com/?attachment_id=2845" class="wp-image-2845"/></figure></li></ul>



<p>降噪方案1：（不好用）</p>



<pre class="wp-block-preformatted">def depoint(img):   #input: gray image
     pixdata = img.load()
     w,h = img.size
     for y in range(1,h-1):
         for x in range(1,w-1):
             count = 0
             if pixdata[x,y-1] &gt; 245:
                 count = count + 1
             if pixdata[x,y+1] &gt; 245:
                 count = count + 1
             if pixdata[x-1,y] &gt; 245:
                 count = count + 1
             if pixdata[x+1,y] &gt; 245:
                 count = count + 1
             if count &gt; 2:
                 pixdata[x,y] = 255
     return img</pre>



<p>似乎只有使用 上/下/左/右 4個方向 shift 1點來判斷，如果遇到較大的噪會無效，處理結果：</p>



<ul class="wp-block-gallery columns-1 is-cropped wp-block-gallery-4 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="280" height="90" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2019/06/test3_depoint.png" alt="" data-id="2846" data-link="https://stackoverflow.max-everyday.com/?attachment_id=2846" class="wp-image-2846"/></figure></li></ul>



<p>效果似乎接近無效，因為黑點都略大。</p>



<p>改服用下面的程式碼：</p>



<pre class="wp-block-preformatted">#二值判断,如果确认是噪声,用改点的上面一个点的灰度进行替换
#该函数也可以改成RGB判断的,具体看需求如何
def getPixel(image,x,y,G,N):
    L = image.getpixel((x,y))
    if L &gt; G:
        L = True
    else:
        L = False
 
    nearDots = 0
    if L == (image.getpixel((x - 1,y - 1)) &gt; G):
        nearDots += 1
    if L == (image.getpixel((x - 1,y)) &gt; G):
        nearDots += 1
    if L == (image.getpixel((x - 1,y + 1)) &gt; G):
        nearDots += 1
    if L == (image.getpixel((x,y - 1)) &gt; G):
        nearDots += 1
    if L == (image.getpixel((x,y + 1)) &gt; G):
        nearDots += 1
    if L == (image.getpixel((x + 1,y - 1)) &gt; G):
        nearDots += 1
    if L == (image.getpixel((x + 1,y)) &gt; G):
        nearDots += 1
    if L == (image.getpixel((x + 1,y + 1)) &gt; G):
        nearDots += 1
 
    if nearDots &lt; N:
        return image.getpixel((x,y-1))
    else:
        return None
 
# 降噪 
# 根据一个点A的RGB值，与周围的8个点的RBG值比较，设定一个值N（0 &lt;N &lt;8），当A的RGB值与周围8个点的RGB相等数小于N时，此点为噪点 
# G: Integer 图像二值化阀值 
# N: Integer 降噪率 0 &lt;N &lt;8 
# Z: Integer 降噪次数 
# 输出 
#  0：降噪成功 
#  1：降噪失败 
def clearNoise(image,G,N,Z):
    draw = ImageDraw.Draw(image)
 
    for i in range(0,Z):
        for x in range(1,image.size[0] - 1):
            for y in range(1,image.size[1] - 1):
                color = getPixel(image,x,y,G,N)
                if color != None:
                    draw.point((x,y),color)

    image.save("test4_clearNoise.jpg")


image = Image.open("captcha.png").convert("L")
image_binary = binarizing(image, 180)
clearNoise(image_binary,50,4,6)
</pre>



<p>結果是有比較好：</p>



<ul class="wp-block-gallery columns-1 is-cropped wp-block-gallery-5 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="280" height="90" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2019/06/test4_clearNoise.jpg" alt="" data-id="2852" data-link="https://stackoverflow.max-everyday.com/?attachment_id=2852" class="wp-image-2852"/></figure></li></ul>



<p>但上面的圖片，還是「無法」使用pytesseract 進行OCR 辨視成功：</p>



<pre class="wp-block-preformatted">code = pytesseract.image_to_string(image_binary, config='digits')
print("code:", code)</pre>



<p>改用OpenCV 看看，OpenCV提供了這種技術的四種去噪方法：<br><a href="https://docs.opencv.org/3.0-beta/modules/photo/doc/denoising.html">https://docs.opencv.org/3.0-beta/modules/photo/doc/denoising.html</a></p>



<ul class="wp-block-list"><li>cv2.fastNlMeansDenoising（） &#8211; 使用單個灰度影象</li><li> cv2.fastNlMeansDenoisingColored（） &#8211; 使用彩色影象。</li><li> cv2.fastNlMeansDenoisingMulti（） &#8211; 用於在短時間內捕獲的影象序列（灰度影象）</li><li> cv2.fastNlMeansDenoisingColoredMulti（） &#8211; 與上面相同，但用於彩色影象。</li></ul>



<p>基本的 opencv 使用範例：</p>



<pre class="wp-block-preformatted">import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('die.png')
dst = cv2.fastNlMeansDenoisingColored(img,None,10,10,7,21)
plt.subplot(121),plt.imshow(img)
plt.subplot(122),plt.imshow(dst)
plt.show()</pre>



<hr class="wp-block-separator"/>



<h4 class="wp-block-heading">總結</h4>



<p>Tesseract-ORC 對於這種弱驗證碼識別率還是可以，大部分字符能夠正確識別出來。只不過有時候會將數字 8 識別為 0。如果圖片驗證碼稍微變得復雜點，識別率大大降低，會經常識別不出來的情況。</p>



<p>如果想要做到識別率較高，那麽需要使用 CNN (Convolutional Neural Network，卷積神經網絡)或者 RNN (Recurrent Neural Network，循環神經網絡)訓練出自己的識別庫。正好機器學習很流行，學習一下也無妨。</p>



<hr class="wp-block-separator"/>



<h4 class="wp-block-heading">卷積神經網路(Convolutional Neural Network, CNN)</h4>



<p>CNN 也是模仿人類大腦的認知方式，譬如我們辨識一個圖像，會先注意到顏色鮮明的點、線、面，之後將它們構成一個個不同的形狀(眼睛、鼻子、嘴巴&#8230;)，這種抽象化的過程就是CNN演算法建立模型的方式。卷積層(Convolution Layer) 就是由點的比對轉成局部的比對，透過一塊塊的特徵研判，逐步堆疊綜合比對結果，就可以得到比較好的辨識結果，過程如下圖。</p>



<ul class="wp-block-gallery columns-1 is-cropped wp-block-gallery-6 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="700" height="167" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2019/06/20001976ks1ZnVMOYD.png" alt="" data-id="2858" data-link="https://stackoverflow.max-everyday.com/2019/06/python-opencv-denoising/20001976ks1znvmoyd/" class="wp-image-2858" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2019/06/20001976ks1ZnVMOYD.png 700w, https://stackoverflow.max-everyday.com/wp-content/uploads/2019/06/20001976ks1ZnVMOYD-600x143.png 600w" sizes="auto, (max-width: 700px) 100vw, 700px" /><figcaption>CNN概念，圖片來源：<a href="https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/">An Intuitive Explanation of Convolutional Neural Networks</a></figcaption></figure></li></ul>



<h2 class="wp-block-heading">卷積層(Convolution Layer)</h2>



<p>如何從點轉成面呢? 就是以圖像的每一點為中心，取周遭 N x N 格的點構成一個面(N 稱為 Kernel Size，N x N 的矩陣權重稱為『卷積核』)，每一格給予不同的權重，計算加權總和，當作這一點的 output，再移動至下一點以相同方式處理，至圖像的最後一點為止，這就是 CNN 的卷積層(Convolution Layer)。</p>



<p>相關文章：<a rel="noreferrer noopener" href="http://cs231n.github.io/convolutional-networks/" target="_blank">CS231n: Convolutional Neural Networks for Visual Recognition</a>&nbsp;<br><a href="http://cs231n.github.io/convolutional-networks/">http://cs231n.github.io/convolutional-networks/</a><br>上面文章的「Convolution Demo」段落，它以動畫的方式說明取樣的方式，有助於更容易了解其原理。</p>



<p>卷積層處理方式與影像處理方法類似，採用滑動視窗(Sliding Window)運算，藉由給予『卷積核』不同的權重組合，就可以偵測形狀的邊、角，也有去除噪音(Noise)及銳化(Sharpen)的效果，萃取這些特徵當作辨識的依據，這也克服了迴歸(Regression)會受『異常點』(Outliers)嚴重影響推測結果的缺點。</p>



<p>資料來源：<br>Day 06：處理影像的利器 &#8212; 卷積神經網路(Convolutional Neural Network)<br><a href="https://ithelp.ithome.com.tw/articles/10191820">https://ithelp.ithome.com.tw/articles/10191820</a></p>



<hr class="wp-block-separator"/>



<h4 class="wp-block-heading">循環神經網路(Recurrent Neural Network, RNN)</h4>



<p>語言通常要考慮前言後語，以免斷章取義，也就是說，建立語言的相關模型，如果能額外考慮上下文的關係，準確率就會顯著提高，因此，學者提出『循環神經網路』(Recurrent Neural Network, RNN)演算法，它是『自然語言處理』領域最常使用的 Neural Network 模型。</p>



<hr class="wp-block-separator"/>



<h4 class="wp-block-heading">相關文章：</h4>



<p>速記AI課程－深度學習入門（二）<br><a href="https://medium.com/@baubibi/%E9%80%9F%E8%A8%98ai%E8%AA%B2%E7%A8%8B-%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92%E5%85%A5%E9%96%80-%E4%BA%8C-954b0e473d7f">https://medium.com/@baubibi/%E9%80%9F%E8%A8%98ai%E8%AA%B2%E7%A8%8B-%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92%E5%85%A5%E9%96%80-%E4%BA%8C-954b0e473d7f</a></p>



<p>我發現，網路上很多AI相關的「入門」等級的教學文章，還滿容易懂和實作的。</p>



<hr class="wp-block-separator"/>



<h4 class="wp-block-heading">相關影片：</h4>



<p>1：[爬蟲實戰] 如何使用Selenium 抓取驗證碼?<br><a href="https://www.youtube.com/watch?v=hF-dJj559ug">https://www.youtube.com/watch?v=hF-dJj559ug</a></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="[爬蟲實戰] 如何使用Selenium 抓取驗證碼?" width="640" height="360" src="https://www.youtube.com/embed/hF-dJj559ug?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>2：[爬蟲實戰] 如何破解高鐵驗證碼 (1) &#8211; 去除圖片噪音點?<br><a href="https://www.youtube.com/watch?v=6HGbKdB4kVY">https://www.youtube.com/watch?v=6HGbKdB4kVY</a></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="[爬蟲實戰] 如何破解高鐵驗證碼 (1) - 去除圖片噪音點?" width="640" height="360" src="https://www.youtube.com/embed/6HGbKdB4kVY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>3：[爬蟲實戰] 如何破解高鐵驗證碼 (2) &#8211; 使用迴歸方法去除多餘弧線?<br><a href="https://www.youtube.com/watch?v=4DHcOPSfC4c">https://www.youtube.com/watch?v=4DHcOPSfC4c</a></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="[爬蟲實戰] 如何破解高鐵驗證碼 (2) - 使用迴歸方法去除多餘弧線?" width="640" height="360" src="https://www.youtube.com/embed/4DHcOPSfC4c?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p><strong>上面影片的原始碼：</strong><br>實作基於CNN的台鐵訂票驗證碼辨識以及透過模仿及資料增強的訓練集產生器 (Simple captcha solver based on CNN and a training set generator by imitating the style of captcha and data augmentation)<br><a href="https://github.com/JasonLiTW/simple-railway-captcha-solver">https://github.com/JasonLiTW/simple-railway-captcha-solver</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2019/06/python-opencv-denoising/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
