Practical Python and OpenCV,3rd Edition 02

基礎說明

什麼是像素

每個圖像都由一組像素組成。 像素是圖像的原始構建塊。沒有比像素更小的單位了。

通常,我們將像素視為出現在圖像中給定位置的光的“顏色”或“強度”。

如果我們將圖像視為網格,則網格中的每個方塊都包含一個像素。

例如,假設我們有一個分辨率為500×300的圖像。這意味著我們的圖像表示為像素網格,有500行和300列。總體而言,我們的圖像總共有 500×300 = 150,000像素。

大多數像素以兩種方式表示:灰度(grayscale)和彩色(color)。在灰度圖像中,每個像素具有0到255之間的值,其中0對應於“黑色”而255對應於“白色”。 0到255之間的值是不同的灰色陰影,其中,接近0的更加的darker,接近於255更加的lighter。

彩色通常以RGB顏色空間表示,one value for the Red component,one for Green,and one for Blue。

RGB中的每一種都由0到255範圍內的整數表示,這表示顏色的“多少”。像素值只需要在[0,255]範圍內,我們通常使用8位無符號整數來表示每種顏色強度。

然後,我們將這些值組合成圖形中的RGB(紅色,綠色,藍色)元組(tuple)。 這個元組就代表我們的顏色。

為了構建一個白色,我們將完全填充每個紅色,綠色和藍色 buckets,如下所示:(255,255,255)。為了創建一個黑色,我們將每個bucket都清空:(0,0,0) ,為了創造一種純紅色,我們將完全填滿紅色的bucket:(255,0,0)。

coordinate system(座標系統)

如上所述,圖像表示為像素網格。 想象一下我們的網格作為一張方格紙。 使用該方格紙,點(0,0)對應於圖像的左上角。 當我們向下和向右移動時,x和y值都會增加。(Python語言是零索引的,這意味著我們總是從零開始計數。),看下圖:

Practical Python and OpenCV,3rd Edition 02

字母“I”放在一張圖紙上.像素是通過他們的(x,y)座標訪問的,我們向右走x列,向下走y行(因為x是橫座標,y是縱座標),記住Python是零索引的:我們從零而不是一開始計數。

代碼

from __future__ import print_function
import argparse
import cv2
ap = argparse.ArgumentParser()
ap.add_argument('-i',"--image",required=True,
help="Path to the image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
cv2.imshow("Original",image)

請記住,OpenCV將圖像表示為NumPy數組。概念上,我們可以將此表示視為一個矩陣。為了訪問像素值,我們只需要提供我們感興趣的像素的x和y座標。但是,重要的是要注意OpenCV以相反的順序存儲RGB channels。 雖然我們通常用Red,Green和Blue(RGB)來思考,但OpenCV實際上按Blue,Green和Red的順序存儲它們(BGR)。如下面的代碼:

(b,g,r) = image[0,0]
print("Pixel at (0,0) - Red:{}, Green: {}, Blue: {}".format(
r,g,b))
image[0,0] = (0,0,255)
(b,g,r) = image[0,0]
print("Pixel at (0,0) - Red: {} , Green: {}, Blue: {}".format(r,
g,b))

解釋

我們首先抓取圖像的左上角的像素,即(0,0)的位置。 這個像素表示為元組.同時,OpenCV以相反的順序存儲RGB像素,因此當我們解包並訪問元組中的每個元素時,我們實際上是以BGR順序查看它們。然後我們將像素RGB顏色打印出來。

接下來,我們操縱圖像中的左上角像素,該像素位於座標(0,0)處,並將其設置為(0,0,255)。 如果我們以RGB格式讀取這個像素值,我們的紅色值為0,綠色值為0,藍色值為255,因此使其成為純藍色。但是,正如我上面提到的,在使用OpenCV時我們需要特別注意。 我們的像素實際上以BGR格式存儲,而不是RGB格式。我們實際上將這個像素讀為255為紅色,0為綠色,0為藍色,使其成為紅色,而不是藍色。

corner = image[0:100,0:100]
cv2.imshow("Corner",corner)
image[0:100,0:100] = (0,255,0)
cv2.imshow("Updated",image)
cv2.waitKey(0)

解釋

接下來我們使用NumPy的數組切片功能來訪問圖像的較大矩形部分。為了訪問圖像較大的部分,Numpy希望我們提供四個索引值,分別是Start y,End y,Start x以及End x。

最後,運行程序即可。

Practical Python and OpenCV,3rd Edition 02

效果圖:

Practical Python and OpenCV,3rd Edition 02

點擊圖片部分,按鍵盤任意鍵結束腳本。

完整的代碼

from __future__ import print_function
import argparse
import cv2
ap = argparse.ArgumentParser()
ap.add_argument('-i',"--image",required=True,
help="Path to the image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
cv2.imshow("Original",image)

(b,g,r) = image[0,0]
print("Pixel at (0,0) - Red:{}, Green: {}, Blue: {}".format(
r,g,b))
image[0,0] = (0,0,255)
(b,g,r) = image[0,0]
print("Pixel at (0,0) - Red: {} , Green: {}, Blue: {}".format(r,
g,b))
corner = image[0:100,0:100]
cv2.imshow("Corner",corner)
image[0:100,0:100] = (0,255,0)
cv2.imshow("Updated",image)
cv2.waitKey(0)

更多參考我的博客:https://0leo0.github.io/2018/OpenCV_python3_02.html


分享到:


相關文章: