

<?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>PIL &#8211; Max的程式語言筆記</title>
	<atom:link href="https://stackoverflow.max-everyday.com/tag/pil/feed/" rel="self" type="application/rss+xml" />
	<link>https://stackoverflow.max-everyday.com</link>
	<description>我要當一個豬頭，快樂過每一天</description>
	<lastBuildDate>Tue, 20 Oct 2020 17:30:54 +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>PIL &#8211; Max的程式語言筆記</title>
	<link>https://stackoverflow.max-everyday.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>PIL 的 getpixel 似乎略慢</title>
		<link>https://stackoverflow.max-everyday.com/2020/10/pil-getpixel-numpy/</link>
					<comments>https://stackoverflow.max-everyday.com/2020/10/pil-getpixel-numpy/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 20 Oct 2020 17:30:53 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[numpy]]></category>
		<category><![CDATA[PIL]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=3566</guid>

					<description><![CDATA[由於想針對影像做處理，使用 loop 去拿ima...]]></description>
										<content:encoded><![CDATA[
<p>由於想針對影像做處理，使用 loop 去拿image 裡的pixel 使用 image.getpixel 似乎太沒有效率，於是使用 numpy.asarray() 把 PIL image object 轉成 array. </p>



<p>使用的範例圖片 width: 921, height 1001, 服用下面的 code 後：</p>



<pre class="wp-block-preformatted">import PIL
import numpy
from PIL import Image
im = Image.open('U_51234.bmp')
data = numpy.asarray(im)
print("shape:", data.shape)
print("100,150:",data[100,150])
print("100,150:",data[100][150])</pre>



<p>取得 shape: (1001, 921)</p>



<p>所以是先 h 再 w, 如果要直接 access array 需要先放 y axis ，再使用 x axis, 與原先的 getpixel(x,y) 順序會相反。</p>



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



<p>Convert between PIL image and NumPy ndarray</p>



<pre class="wp-block-code"><code>image = Image.open(“max-demo.jpg”)   # image is a PIL image 
array = numpy.array(image)          # array is a numpy array 
image2 = Image.fromarray(array)   # image2 is a PIL image
</code></pre>



<p>Convert between PIL image and PyOpenCV matrix</p>



<pre class="wp-block-code"><code>image = Image.open(“max-demo.jpg”)                  # image is a PIL image
mat = pyopencv.Mat.from_pil_image(image)  # mat is a PyOpenCV matrix 
image2 = mat.to_pil_image()                        # image2 is a PIL image
</code></pre>



<p>Convert between OpenCV image and NumPy ndarray</p>



<pre class="wp-block-code"><code>cimg = cv.LoadImage("max-demo.jpg", cv.CV_LOAD_IMAGE_COLOR)   # cimg is a OpenCV image 
pimg = Image.fromstring("RGB", cv.GetSize(cimg), cimg.tostring())  # pimg is a PIL image 
array = numpy.array(pimg)     # array is a numpy array 
pimg2 = cv.fromarray(array)    # pimg2 is a OpenCV image</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2020/10/pil-getpixel-numpy/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 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 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 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 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="(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 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 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 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>
		<item>
		<title>[Python] 檢查照片 exif 進行自動轉向</title>
		<link>https://stackoverflow.max-everyday.com/2017/02/python-image-exif-rotate/</link>
					<comments>https://stackoverflow.max-everyday.com/2017/02/python-image-exif-rotate/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 13 Feb 2017 18:18:37 +0000</pubDate>
				<category><![CDATA[Dropboxlike開發筆記]]></category>
		<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[Dropboxlike]]></category>
		<category><![CDATA[PIL]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=136</guid>

					<description><![CDATA[範例： https://github.com/a...]]></description>
										<content:encoded><![CDATA[<p>範例：<br>
<a href="https://github.com/agschwender/pilbox/blob/af3b5050acf492ed584ae5a3c2813e1fe207a762/pilbox/image.py">https://github.com/agschwender/pilbox/blob/af3b5050acf492ed584ae5a3c2813e1fe207a762/pilbox/image.py</a></p>
<p>&nbsp;
</p><pre>_orientation_to_rotation = {
    3: 180,
    6: 90,
    8: 270
}

deg = 0
if self._orig_format == "JPEG":
    try:
        exif = self.img._getexif() or dict()
        deg = _orientation_to_rotation.get(exif.get(274, 0), 0)
    except Exception:
        logger.warn('unable to parse exif')

self.img = self.img.rotate(360 - int(deg))

</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h4>相關文章：</h4>
<p>Does PNG contain EXIF data like JPG?<br>
<a href="http://stackoverflow.com/questions/9542359/does-png-contain-exif-data-like-jpg">http://stackoverflow.com/questions/9542359/does-png-contain-exif-data-like-jpg</a></p>
<p>&nbsp;</p>


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



<h4 class="wp-block-heading">安裝Pillow</h4>



<p>在命令行下直接通過pip安裝：<br></p>



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



<p>或</p>



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



<p>如果遇到Permission denied安裝失敗，請加上sudo重試。如果同時有 python2 + python3 請把上面的 python 換成  python3 即可。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2017/02/python-image-exif-rotate/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How do I resize an image using PIL and maintain its aspect ratio?</title>
		<link>https://stackoverflow.max-everyday.com/2016/07/how-do-i-resize-an-image-using-pil-and-maintain-its-aspect-ratio/</link>
					<comments>https://stackoverflow.max-everyday.com/2016/07/how-do-i-resize-an-image-using-pil-and-maintain-its-aspect-ratio/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Thu, 30 Jun 2016 17:14:36 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[PIL]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=77</guid>

					<description><![CDATA[我有一個資料夾，裡的圖檔是 96&#215;96...]]></description>
										<content:encoded><![CDATA[<p>我有一個資料夾，裡的圖檔是 96&#215;96, 我希望在這一個資料夾下的檔案被異動時，會自動產生縮圖(64&#215;64)到其他的資料夾下。</p>
<p><a href="http://max-everyday.com/wp-content/uploads/2016/06/Screenshot-2016-06-30-06.51.12.jpg"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-923" src="http://max-everyday.com/wp-content/uploads/2016/06/Screenshot-2016-06-30-06.51.12.jpg" alt="Screenshot 2016-06-30 06.51.12" width="830" height="436"></a></p>
<p>PIL 是 Python 下最有名的影像處理套件。</p>
<p><a href="http://pillow.readthedocs.io/en/3.0.x/index.html">http://pillow.readthedocs.io/en/3.0.x/index.html</a></p>
<p>這個套件，似乎在升級改版本，把一些比較少人用的屬性或方法在新版本裡拿掉，新版本也加入了更多新的功能。一般人應該都只會使用基本功能，有需要使用進階功能的時候可能要留意 PIL 的版本。</p>
<hr>
<p>範例1號：縮圖</p>
<blockquote><p>#!/usr/bin/env python<br>
#encoding=utf-8</p>
<p>from PIL import Image</p>
<p>im = Image.open( &#8220;tab_icon_countrys.png&#8221; )<br>
print im.size</p>
<p>width = 64<br>
ratio = float(width)/im.size[0]<br>
height = int(im.size[1]*ratio)<br>
nim = im.resize( (width, height), Image.BILINEAR )<br>
print nim.size<br>
nim.save( &#8220;resized.png&#8221; )</p></blockquote>
<p>執行結果：</p>
<p>(96, 96)<br>
(64, 64)</p>
<p>說明：</p>
<p>原本圖檔&nbsp;tab_icon_countrys.png 是 96&#215;96, 等比率縮成 64&#215;64.</p>
<hr>
<p>列出目前目錄下的 *.png 檔案：</p>
<blockquote><p>
</p><p class="p1"><span class="s1">#!/usr/bin/env python</span></p>
<p class="p1"><span class="s1">#encoding=utf-8</span></p>
<p class="p2"><span class="s2">from</span><span class="s1"> glob </span><span class="s2">import</span><span class="s1"> glob</span></p>
<p class="p2"><span class="s2">from</span><span class="s1"> os.path </span><span class="s2">import</span><span class="s1"> splitext</span></p>
<p class="p2"><span class="s2">from</span><span class="s1"> PIL </span><span class="s2">import</span><span class="s1"> Image</span></p>
<p class="p2"><span class="s1">imagelist = glob( </span><span class="s3">&#8220;*.[pP][nN][gG]&#8221;</span><span class="s1"> )</span></p>
<p class="p2"><span class="s2">for</span><span class="s1"> img </span><span class="s2">in</span><span class="s1"> imagelist:</span></p>
<p class="p2"><span class="s1"><span class="Apple-converted-space">&nbsp; &nbsp; </span>im = Image.open(img)</span></p>
<p class="p2"><span class="s1"><span class="Apple-converted-space">&nbsp; &nbsp; </span>png = splitext(img)[</span><span class="s4">0</span><span class="s1">]+</span><span class="s3">&#8220;-thumbnail.png&#8221;</span></p>
<p class="p1"><span class="s5"><span class="Apple-converted-space">&nbsp; &nbsp; </span></span><span class="s1">#im.save(png)</span></p>
<p class="p2"><span class="s1"><span class="Apple-converted-space">&nbsp; &nbsp; </span></span><span class="s2">print</span><span class="s1"> png</span></p>
</blockquote>
<hr>
<p>把 sample 1 + sample 2 結合起來，取得 sample 3號：</p>
<blockquote><p>
</p><p class="p1"><span class="s1">#!/usr/bin/env python</span></p>
<p class="p1"><span class="s1">#encoding=utf-8</span></p>
<p class="p2"><span class="s2">from</span><span class="s1"> glob </span><span class="s2">import</span><span class="s1"> glob</span></p>
<p class="p2"><span class="s2">from</span><span class="s1"> os.path </span><span class="s2">import</span><span class="s1"> splitext</span></p>
<p class="p2"><span class="s2">from</span><span class="s1"> PIL </span><span class="s2">import</span><span class="s1"> Image</span></p>
<p class="p2"><span class="s1">imagelist = glob( </span><span class="s3">&#8220;*.[pP][nN][gG]&#8221;</span><span class="s1"> )</span></p>
<p class="p2"><span class="s2">for</span><span class="s1"> img </span><span class="s2">in</span><span class="s1"> imagelist:</span></p>
<p class="p2"><span class="s1"><span class="Apple-converted-space">&nbsp; &nbsp; </span>im = Image.open(img)</span></p>
<p class="p2"><span class="s1"><span class="Apple-converted-space">&nbsp; &nbsp; </span>filename = splitext(img)[</span><span class="s4">0</span><span class="s1">] + </span><span class="s3">&#8220;.png&#8221;</span></p>
<p class="p2"><span class="s1"><span class="Apple-converted-space">&nbsp; &nbsp; </span></span><span class="s2">print</span> <span class="s3">&#8220;Filename: &#8220;</span><span class="s1"> + filename</span></p>
<p class="p2"><span class="s1"><span class="Apple-converted-space">&nbsp; &nbsp; </span>width = </span><span class="s4">96</span></p>
<p class="p2"><span class="s1"><span class="Apple-converted-space">&nbsp; &nbsp; </span>png_filepath = </span><span class="s3">&#8220;../drawable-xxhdpi/&#8221;</span><span class="s1"> + filename</span></p>
<p class="p2"><span class="s1"><span class="Apple-converted-space">&nbsp; &nbsp; </span>nim = im.resize( (width, width), Image.BILINEAR )</span></p>
<p class="p2"><span class="s1"><span class="Apple-converted-space">&nbsp; &nbsp; </span>nim.save(png_filepath)</span></p>
</blockquote>


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



<h4 class="wp-block-heading">安裝Pillow</h4>



<p>在命令行下直接通過pip安裝：<br></p>



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



<p>或</p>



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



<p>如果遇到Permission denied安裝失敗，請加上sudo重試。如果同時有 python2 + python3 請把上面的 python 換成  python3 即可。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2016/07/how-do-i-resize-an-image-using-pil-and-maintain-its-aspect-ratio/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
