Ⅰ python處理圖片數據
目錄
1.機器是如何存儲圖像的?
2.在Python中讀取圖像數據
3.從圖像數據中提取特徵的方法#1:灰度像素值特徵
4.從圖像數據中提取特徵的方法#2:通道的平均像素值
5.從圖像數據中提取特徵的方法#3:提取邊緣
是一張數字8的圖像,仔細觀察就會發現,圖像是由小方格組成的。這些小方格被稱為像素。
但是要注意,人們是以視覺的形式觀察圖像的,可以輕松區分邊緣和顏色,從而識別圖片中的內容。然而機器很難做到這一點,它們以數字的形式存儲圖像。請看下圖:
機器以數字矩陣的形式儲存圖像,矩陣大小取決於任意給定圖像的像素數。
假設圖像的尺寸為180 x 200或n x m,這些尺寸基本上是圖像中的像素數(高x寬)。
這些數字或像素值表示像素的強度或亮度,較小的數字(接近0)表示黑色,較大的數字(接近255)表示白色。通過分析下面的圖像,讀者就會弄懂到目前為止所學到的知識。
下圖的尺寸為22 x 16,讀者可以通過計算像素數來驗證:
圖片源於機器學習應用課程
剛才討論的例子是黑白圖像,如果是生活中更為普遍的彩色呢?你是否認為彩色圖像也以2D矩陣的形式存儲?
彩色圖像通常由多種顏色組成,幾乎所有顏色都可以從三原色(紅色,綠色和藍色)生成。
因此,如果是彩色圖像,則要用到三個矩陣(或通道)——紅、綠、藍。每個矩陣值介於0到255之間,表示該像素的顏色強度。觀察下圖來理解這個概念:
圖片源於機器學習應用課程
左邊有一幅彩色圖像(人類可以看到),而在右邊,紅綠藍三個顏色通道對應三個矩陣,疊加三個通道以形成彩色圖像。
請注意,由於原始矩陣非常大且可視化難度較高,因此這些不是給定圖像的原始像素值。此外,還可以用各種其他的格式來存儲圖像,RGB是最受歡迎的,所以筆者放到這里。讀者可以在此處閱讀更多關於其他流行格式的信息。
用Python讀取圖像數據
下面開始將理論知識付諸實踐。啟動Python並載入圖像以觀察矩陣:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from skimage.io import imread, imshow
image = imread('image_8_original.png', as_gray=True)
imshow(image)
#checking image shape
image.shape, image
(28,28)
矩陣有784個值,而且這只是整個矩陣的一小部分。用一個LIVE編碼窗口,不用離開本文就可以運行上述所有代碼並查看結果。
下面來深入探討本文背後的核心思想,並探索使用像素值作為特徵的各種方法。
方法#1:灰度像素值特徵
從圖像創建特徵最簡單的方法就是將原始的像素用作單獨的特徵。
考慮相同的示例,就是上面那張圖(數字『8』),圖像尺寸為28×28。
能猜出這張圖片的特徵數量嗎?答案是與像素數相同!也就是有784個。
那麼問題來了,如何安排這784個像素作為特徵呢?這樣,可以簡單地依次追加每個像素值從而生成特徵向量。如下圖所示:
下面來用Python繪制圖像,並為該圖像創建這些特徵:
image = imread('puppy.jpeg', as_gray=True)
image.shape, imshow(image)
(650,450)
該圖像尺寸為650×450,因此特徵數量應為297,000。可以使用NumPy中的reshape函數生成,在其中指定圖像尺寸:
#pixel features
features = np.reshape(image, (660*450))
features.shape, features
(297000,)
array([0.96470588, 0.96470588, 0.96470588, ..., 0.96862745, 0.96470588,
0.96470588])
這里就得到了特徵——長度為297,000的一維數組。很簡單吧?在實時編碼窗口中嘗試使用此方法提取特徵。
但結果只有一個通道或灰度圖像,對於彩色圖像是否也可以這樣呢?來看看吧!
方法#2:通道的平均像素值
在讀取上一節中的圖像時,設置了參數『as_gray = True』,因此在圖像中只有一個通道,可以輕松附加像素值。下面刪除參數並再次載入圖像:
image = imread('puppy.jpeg')
image.shape
(660, 450, 3)
這次,圖像尺寸為(660,450,3),其中3為通道數量。可以像之前一樣繼續創建特徵,此時特徵數量將是660*450*3 = 891,000。
或者,可以使用另一種方法:
生成一個新矩陣,這個矩陣具有來自三個通道的像素平均值,而不是分別使用三個通道中的像素值。
下圖可以讓讀者更清楚地了解這一思路:
這樣一來,特徵數量保持不變,並且還能考慮來自圖像全部三個通道的像素值。
image = imread('puppy.jpeg')
feature_matrix = np.zeros((660,450))
feature_matrix.shape
(660, 450)
現有一個尺寸為(660×450×3)的三維矩陣,其中660為高度,450為寬度,3是通道數。為獲取平均像素值,要使用for循環:
for i in range(0,iimage.shape[0]):
for j in range(0,image.shape[1]):
feature_matrix[i][j] = ((int(image[i,j,0]) + int(image[i,j,1]) + int(image[i,j,2]))/3)
新矩陣具有相同的高度和寬度,但只有一個通道。現在,可以按照與上一節相同的步驟進行操作。依次附加像素值以獲得一維數組:
features = np.reshape(feature_matrix, (660*450))
features.shape
(297000,)
方法#3:提取邊緣特徵
請思考,在下圖中,如何識別其中存在的對象:
識別出圖中的對象很容易——狗、汽車、還有貓,那麼在區分的時候要考慮哪些特徵呢?形狀是一個重要因素,其次是顏色,或者大小。如果機器也能像這樣識別形狀會怎麼樣?
類似的想法是提取邊緣作為特徵並將其作為模型的輸入。稍微考慮一下,要如何識別圖像中的邊緣呢?邊緣一般都是顏色急劇變化的地方,請看下圖:
筆者在這里突出了兩個邊緣。這兩處邊緣之所以可以被識別是因為在圖中,可以分別看到顏色從白色變為棕色,或者由棕色變為黑色。如你所知,圖像以數字的形式表示,因此就要尋找哪些像素值發生了劇烈變化。
假設圖像矩陣如下:
圖片源於機器學習應用課程
該像素兩側的像素值差異很大,於是可以得出結論,該像素處存在顯著的轉變,因此其為邊緣。現在問題又來了,是否一定要手動執行此步驟?
當然不!有各種可用於突出顯示圖像邊緣的內核,剛才討論的方法也可以使用Prewitt內核(在x方向上)來實現。以下是Prewitt內核:
獲取所選像素周圍的值,並將其與所選內核(Prewitt內核)相乘,然後可以添加結果值以獲得最終值。由於±1已經分別存在於兩列之中,因此添加這些值就相當於獲取差異。
還有其他各種內核,下面是四種最常用的內核:
圖片源於機器學習應用課程
現在回到筆記本,為同一圖像生成邊緣特徵:
#importing the required libraries
import numpy as np
from skimage.io import imread, imshow
from skimage.filters import prewitt_h,prewitt_v
import matplotlib.pyplot as plt
%matplotlib inline
#reading the image
image = imread('puppy.jpeg',as_gray=True)
#calculating horizontal edges using prewitt kernel
edges_prewitt_horizontal = prewitt_h(image)
#calculating vertical edges using prewitt kernel
edges_prewitt_vertical = prewitt_v(image)
imshow(edges_prewitt_vertical, cmap='gray')
Ⅱ Python簡單加密操作
加密是將一個明文數據,按照指定的演算法,運算得到一個其他的可以隱藏真實信息的密文數據,這個過程稱為加密;處理的演算法稱為加密演算法;用到的關鍵數據稱為密鑰。
解密是按照制定的演算法和關鍵數據,將一個密文數據進行逆向運算得到的正確的明文數據的過程
如:用戶賬號密碼存儲,此時任何人都不能查看該用戶的明文密碼
1.原始數據
2.編碼(轉換為位元組數據)
3.使用演算法加密
4.利用鹽值更新密文
5.得到加密後的數據
編碼:字元串.encode(編碼名稱)——>位元組數據
解碼:位元組數據.decode(編碼名稱)——>字元串數據
==========================================
Ⅲ 相似圖片檢測:感知哈希演算法之dHash的Python實現
某些情況下,我們需要檢測圖片之間的相似性,進行我們需要的處理:刪除同一張圖片、標記盜版等。
如何判斷是同一張圖片呢?最簡單的方法是使用加密哈希(例如MD5, SHA-1)判斷。但是局限性非常大。例如一個txt文檔,其MD5值是根據這個txt的二進制數據計算的,如果是這個txt文檔的完全復製版,那他們的MD5值是完全相同的。但是,一旦改變副本的內容,哪怕只是副本的縮進格式,其MD5也會天差地別。因此加密哈希只能用於判斷兩個完全一致、未經修改的文件,如果是一張經過調色或者縮放的圖片,根本無法判斷其與另一張圖片是否為同一張圖片。
那麼如何判斷一張被PS過的圖片是否與另一張圖片本質上相同呢?比較簡單、易用的解決方案是採用感知哈希演算法(Perceptual Hash Algorithm)。
感知哈希演算法是一類演算法的總稱,包括aHash、pHash、dHash。顧名思義,感知哈希不是以嚴格的方式計算Hash值,而是以更加相對的方式計算哈希值,因為「相似」與否,就是一種相對的判定。
如果我們要計算上圖的dHash值,第一步是把它 縮放到足夠小 。為什麼需要縮放呢?因為原圖的解析度一般都非常高。一張 200*200 的圖片,就有整整4萬個像素點,每一個像素點都保存著一個RGB值,4萬個RGB,是相當龐大的信息量,非常多的細節需要處理。因此,我們需要把圖片縮放到非常小,隱藏它的細節部分,只見森林,不見樹木。建議縮放為9*8,雖然可以縮放為任意大小,但是這個值是相對合理的。而且寬度為9,有利於我們轉換為hash值,往下面看,你就明白了。
(感謝評論區 隔壁萬能的小黑 同學,建議在 image.resize 中加上Image.ANTIALIAS參數,加上此參數將會對所有可以影響輸出像素的輸入像素進行高質量的重采樣濾波)
dHash全名為差異值hash,通過計算相鄰像素之間的顏色強度差異得出。我們縮放後的圖片,細節已經被隱藏,信息量已經變少。但是還不夠,因為它是彩色的,由RGB值組成。白色表示為(255,255,255),黑色表示為(0,0,0),值越大顏色越亮,越小則越暗。每種顏色都由3個數值組成,也就是紅、綠、藍的值 。如果直接使用RGB值對比顏色強度差異,相當復雜,因此我們轉化為灰度值——只由一個0到255的整數表示灰度。這樣的話就將三維的比較簡化為了一維比較。
差異值是通過計算每行相鄰像素的強度對比得出的。我們的圖片為9*8的解析度,那麼就有8行,每行9個像素。差異值是每行分別計算的,也就是第二行的第一個像素不會與第一行的任何像素比較。每一行有9個像素,那麼就會產生8個差異值,這也是為何我們選擇9作為寬度,因為8bit剛好可以組成一個byte,方便轉換為16進制值。
如果前一個像素的顏色強度大於第二個像素,那麼差異值就設置為True(也就是1),如果不大於第二個像素,就設置為False(也就是0)。
我們將差異值數組中每一個值看做一個bit,每8個bit組成為一個16進制值,將16進制值連接起來轉換為字元串,就得出了最後的dHash值。
漢明距離這個概念不止運用於圖片對比領域,也被使用於眾多領域,具體的介紹可以參見Wikipedia。
漢明距離表示將A修改成為B,需要多少個步驟。比如字元串「abc」與「ab3」,漢明距離為1,因為只需要修改「c」為「3」即可。
dHash中的漢明距離是通過計算差異值的修改位數。我們的差異值是用0、1表示的,可以看做二進制。二進制0110與1111的漢明距離為2。
我們將兩張圖片的dHash值轉換為二進制difference,並取異或。計算異或結果的「1」的位數,也就是不相同的位數,這就是漢明距離。
如果傳入的參數不是兩張圖的dHash值,而是直接比較兩張圖片,那麼不需要生成dHash值,直接用Step3中的difference數組,統計不相同的位數,就是漢明距離。
一般來說,漢明距離小於5,基本就是同一張圖片。大家可以根據自己的實際情況,判斷漢明距離臨界值為多少。
https://github.com/hjaurum/DHash
Ⅳ 怎麼樣給python文件加密
簡單模式:
from hashlib import md5
def md5_file(name):
m = md5()
a_file = open(name, 'rb') #需要使用二進制格式讀取文件內容
m.update(a_file.read())
a_file.close()
return m.hexdigest()
if __main__ == '__init__':
print md5_file('d:/test.txt')
大文件速度更快一點的方式
#!/usr/bin/python
#encoding=utf-8
import io
import sys
import hashlib
import string
def printUsage():
print ('''''Usage: [python] pymd5sum.py ''')
def main():
if(sys.argv.__len__()==2):
#print(sys.argv[1])
m = hashlib.md5()
file = io.FileIO(sys.argv[1],'r')
bytes = file.read(1024)
while(bytes != b''):
m.update(bytes)
bytes = file.read(1024)
file.close()
#md5value = ""
md5value = m.hexdigest()
print(md5value+"\t"+sys.argv[1])
#dest = io.FileIO(sys.argv[1]+".CHECKSUM.md5",'w')
#dest.write(md5value)
#dest.close()
else:
printUsage()
main()
Ⅳ python文本加密是什麼
python文本加密是Python 提供了諸如 hashlib,base64 等便於使用的加密庫,我們可以藉助異或操作,實現一個簡單的文件加密程序。
通過了解異或操作的性質,加密原理就非常清晰了。
首先將文件轉換成二進制數,再生成與該二進制數等長的隨機密鑰,將二進制數與密鑰進行異或操作,得到加密後的二進制數。
將加密後的二進製程序與密鑰進行異或操作,就得到原二進制數,最後將原二進制數恢復成文本文件。
相關拓展
加密,是以某種特殊的演算法改變原有的信息數據,使得未授權的用戶即使獲得了已加密的信息,但因不知解密的方法,仍然無法了解信息的內容。
加密之所以安全,絕非因不知道加密解密演算法方法,而是加密的密鑰是絕對的隱藏,流行的RSA和AES加密演算法都是完全公開的,一方取得已加密的數據,就算知道加密演算法也好,若沒有加密的密鑰,也不能打開被加密保護的信息。
單單隱蔽加密演算法以保護信息,在學界和業界已有相當討論,一般認為是不夠安全的。公開的加密演算法是給黑客和加密家長年累月攻擊測試,對比隱蔽的加密演算法要安全得多。
盡管加密或為了安全目的對信息解碼這個概念十分簡單,但在這里仍需對其進行解釋。數據加密的基本過程包括對稱為明文的原來可讀信息進行翻譯,譯成稱為密文或密碼的代碼形式。該過程的逆過程為解密,即將該編碼信息轉化為其原來的形式的過程。
以上內容參考 網路-加密
Ⅵ python的加密方式: rsa加密和解密
RSA加密是一種非對稱加密,通常使用公鑰加密,私鑰解密。
生成文件如下圖:
可以將生成的公鑰、私鑰粘貼復制存儲起來,以便使用:
在使用中, 通常會先對數據進行bas64加密, 再對加密後的內容使用rsa加密, 最後對rsa解密後的內容進行bas64解密.
Ⅶ 什麼是"信息隱藏"技術,python中如何實現信息隱藏
隱寫術 數字水印 匿名技術(用於網路隱藏個人信息啊什麼的) 可視密碼(又叫疊像術)
Ⅷ 如何用Python編寫密碼隱藏函數
def use_list(): str_before=input("請輸入明文:") str_change=str_before.lower() str_list=list(str_change) str_list_change=str_list i=0 whilei
Ⅸ python爬取圖片時忽略了一些圖片
真實圖片地址是在客戶端javascript代碼中計算出來的.
你需要尋找
<spanclass="img-hash">tnaS5qcGc=</span>
這樣的內容,取出
tnaS5qcGc=
這段內容,做base64解碼即得圖片地址。
相應的腳本在
//cdn.jandan.net/static/min/.03100001.js
這段內容你通過get_page()爬到地頁面中有,同樣,該頁面中有這樣的html(為便於閱讀已重排格式):
<divclass="text">
<spanclass="righttext">
<ahref="//jandan.net/ooxx/page-34#comment-4001800">4001800</a>
</span>
<p>
<imgsrc="//img.jandan.net/img/blank.gif"onload="jandan_load_img(this)"/>
<spanclass="img-hash">tnaS5qcGc=</span>
</p>
</div>
這個img的onload調用的函數就在前面給出的那個js文件中:
functionjandan_load_img(b){
vard=$(b);
varf=d.next("span.img-hash");
vare=f.text();
f.remove();
varc=(e,"");
vara=$('<ahref="'+c.replace(/(//w+.sinaimg.cn/)(w+)(/.+.(gif|jpg|jpeg))/,"$1large$3")+
'"target="_blank"class="view_img_link">[查看原圖]</a>');
d.before(a);
d.before("<br>");
d.removeAttr("onload");
d.attr("src",location.protocol+c.replace(/(//w+.sinaimg.cn/)(w+)(/.+.gif)/,"$1thumb180$3"));
if(/.gif$/.test(c)){
d.attr("org_src",location.protocol+c);
b.onload=function(){
add_img_loading_mask(this,load_sina_gif)
}
}
它調用了對img-hash的內容做解碼,這個函數同樣在這個js文件中:
var=function(o,y,g){
vard=o;varl="DECODE";
vary=y?y:"";
varg=g?g:0;
varh=4;
y=md5(y);
varx=md5(y.substr(0,16));
varv=md5(y.substr(16,16));
...中間部分略去...
if(l=="DECODE"){
m=base64_encode(m);
varc=newRegExp("=","g");
m=m.replace(c,"");
m=u+m;
m=base64_decode(d)
}
returnm
};
你只需要在Python使用相應的庫對抓取到的img-hash內容做解碼即可得到圖片地址。
你使用了str的find來從文本中定位位置,這樣做太麻煩了,太多的代碼細節,使用re模塊做正則匹配就簡單很多,更快的是直接使用現有的爬蟲庫.
使用re進行正則匹配,只需要使用正則式'<spanclass="img-hash">(.+?)<'即可提取出該頁面中所有加密的圖片地址。
importre
importbase64
pat=re.compile('<spanclass="img-hash">(.+?)<')
...
defget_imgurls(url):
urls=[]
forimgurlinpat.findall(url_open(url).decode('utf-8')):
.append(str(base64.b64decode(imgurl),'utf-8'))
returnurls
然後就可以對get_imgurls返回的列表遍歷,逐個交給save_img處理了。
使用爬取庫也只需要尋找span,從中找出class='img-hash'即可讀取text。