Interface2017年05月号新画像処理101を読む

アファイン変換で平行移動して、画像サイズを大きくした場合

#http://imagingsolution.blog107.fc2.com/blog-entry-284.html

import math as m

img_src = cv2.imread("data/img_4-2.bmp")
eight,width,ch = img_src.shape
"""
warpAffine
画像のアフィン変換を行います.

パラメタ:
src – 入力画像
M – 2×3 の変換行列
dsize – 出力画像のサイズ
flags – 補間手法( resize() を参照してください)と, M が逆変換( dst  \rightarrow src )であることを意味するオプションフラグ WARP_INVERSE_MAP の組み合わせ
borderMode – ピクセル外挿手法. borderInterpolate() を参照してください. borderMode = BORDER_TRANSPARENT の場合,入力画像中の「はずれ値」に対応する出力画像中のピクセルが,この関数では変更されないことを意味します
borderValue – 定数境界モードで利用されるピクセル値.デフォルトでは 0 です
"""
deg = m.tan(m.pi/6)
mat = np.float32(
[[1,-deg,width-1],
[0,1,0]])

img_dst = cv2.warpAffine(img_src,mat,(int(width+eight*deg),eight))
#描画する
cv2.imshow("img_src",img_src)
cv2.imshow("img_dst",img_dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

f:id:bitop:20180218082829p:plain

f:id:bitop:20180218083518p:plain

Interface2017年05月号新画像処理101を読む

アファイン変換で平行移動した場合

#http://imagingsolution.blog107.fc2.com/blog-entry-284.html

import math as m

img_src = cv2.imread("data/img_4-2.bmp")
eight,width,ch = img_src.shape
"""
warpAffine
画像のアフィン変換を行います.

パラメタ:
src – 入力画像
M – 2×3 の変換行列
dsize – 出力画像のサイズ
flags – 補間手法( resize() を参照してください)と, M が逆変換( dst  \rightarrow src )であることを意味するオプションフラグ WARP_INVERSE_MAP の組み合わせ
borderMode – ピクセル外挿手法. borderInterpolate() を参照してください. borderMode = BORDER_TRANSPARENT の場合,入力画像中の「はずれ値」に対応する出力画像中のピクセルが,この関数では変更されないことを意味します
borderValue – 定数境界モードで利用されるピクセル値.デフォルトでは 0 です
"""
mat = np.float32(
[[1,-m.tan(m.pi/6),width-1],
[0,1,0]])

img_dst = cv2.warpAffine(img_src,mat,(width,eight))
#描画する
cv2.imshow("img_src",img_src)
cv2.imshow("img_dst",img_dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

f:id:bitop:20180218082829p:plain

f:id:bitop:20180218083323p:plain

Interface2017年05月号新画像処理101を読む

4-2 ひずみ補正等に使える並行四辺形変換「スキュー変換(水平)」

アファイン変換で平行移動していない場合

#http://imagingsolution.blog107.fc2.com/blog-entry-284.html

import math as m

img_src = cv2.imread("data/img_4-2.bmp")
eight,width,ch = img_src.shape
"""
warpAffine
画像のアフィン変換を行います.

パラメタ:
src – 入力画像
M – 2×3 の変換行列
dsize – 出力画像のサイズ
flags – 補間手法( resize() を参照してください)と, M が逆変換( dst  \rightarrow src )であることを意味するオプションフラグ WARP_INVERSE_MAP の組み合わせ
borderMode – ピクセル外挿手法. borderInterpolate() を参照してください. borderMode = BORDER_TRANSPARENT の場合,入力画像中の「はずれ値」に対応する出力画像中のピクセルが,この関数では変更されないことを意味します
borderValue – 定数境界モードで利用されるピクセル値.デフォルトでは 0 です
"""
mat = np.float32(
[[1,-m.tan(m.pi/6),0],
[0,1,0]])

img_dst = cv2.warpAffine(img_src,mat,(width,eight))
#描画する
cv2.imshow("img_src",img_src)
cv2.imshow("img_dst",img_dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

f:id:bitop:20180218082829p:plain

f:id:bitop:20180218083027p:plain

Interface2017年05月号新画像処理101を読む

技4 変形/移動 処理

4-1 画像を変形したいとき使う回転変形

img_src = cv2.imread("data/img_4-1.bmp")
eight,width,ch = img_src.shape
"""
getRotationMatrix2D
回転変換行列の算出
パラメタ:
center – 入力画像中にある回転中心
angle – 度単位で表される回転角度.正の値は反時計回りを意味します(座標原点が,左上コーナーにあると仮定されます)
scale – 等方性のスケールファクタ
"""
"""
warpAffine
画像のアフィン変換を行います.

パラメタ:
src – 入力画像
M – 2×3 の変換行列
dsize – 出力画像のサイズ
flags – 補間手法( resize() を参照してください)と, M が逆変換( dst  \rightarrow src )であることを意味するオプションフラグ WARP_INVERSE_MAP の組み合わせ
borderMode – ピクセル外挿手法. borderInterpolate() を参照してください. borderMode = BORDER_TRANSPARENT の場合,入力画像中の「はずれ値」に対応する出力画像中のピクセルが,この関数では変更されないことを意味します
borderValue – 定数境界モードで利用されるピクセル値.デフォルトでは 0 です
"""
mat = cv2.getRotationMatrix2D((width/2,eight/2),45,1)
img_dst = cv2.warpAffine(img_src,mat,(width,eight))
#描画する
cv2.imshow("img_src",img_src)
cv2.imshow("img_dst",img_dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

f:id:bitop:20180218070629p:plain

f:id:bitop:20180218070700p:plain

Interface2017年05月号新画像処理101を読む

A-5 緻密な濃淡表現を実現する「バークス型誤差拡散法」

img_src = cv2.imread("data/img_A-3.bmp")
img_dst = np.empty_like(img_src)
#座標の大きさ
eight = img_src.shape[0]
width = img_src.shape[1]

for y in range(0,eight):
    for x in range(0,width):
        img_dst[y,x] = img_src[y,x]

for y in range(0,eight):
    for x in range(0,width):
        temp = float(img_src[y,x,0])
        if temp > 127:
            e = temp - 255
        else:
            e = temp 

        if 2 <= x < width - 2 and 2 <= y < eight-1:
            img_dst[y    ,x+1,0] = float(img_dst[y,x+1,0]) + 0.25*e  
            img_dst[y    ,x+2,0] = float(img_dst[y,x+2,0]) + 0.125*e  
            img_dst[y+1,x-2,0] = float(img_dst[y+1,x-2,0]) + 0.0625*e
            img_dst[y+1,x-1,0] = float(img_dst[y+1,x-1,0]) + 0.25*e
            img_dst[y+1,x   ,0] = float(img_dst[y+1,x,0]) + 0.25*e              
            img_dst[y+1,x+1,0] = float(img_dst[y+1,x+1,0]) + 0.125*e
            img_dst[y+1,x+2,0] = float(img_dst[y+1,x+2,0]) + 0.0625*e

for y in range(0,eight):
    for x in range(0,width):
        temp = img_dst[y,x,0]
        img_dst[y,x] = [temp,temp,temp]


#描画する
cv2.imshow("img_src",img_src)
cv2.imshow("img_dst",img_dst)

cv2.waitKey(0)
cv2.destroyAllWindows()

#ヒストグラム
fig = plt.figure()
ax1 = fig.add_subplot(211) #総行数,総列数、サブプロット番号
ax2 = fig.add_subplot(212)

color_list = ["gray"]
ax2.set_ylim(0,5000)
for i,j in enumerate(color_list):
    hist = cv2.calcHist([img_src],[i],None,[256],[0,256])
    ax1.plot(hist,color = j)

color_list = ["gray"]
ax2.set_ylim(0,5000)
for i,j in enumerate(color_list):
    hist = cv2.calcHist([img_dst],[i],None,[256],[0,256])
    ax2.plot(hist,color = j)

今回もうまくいかない

f:id:bitop:20180212062412p:plain

f:id:bitop:20180217074738p:plain

f:id:bitop:20180217074819p:plain

Interface2017年05月号新画像処理101を読む

A-4 パターンを用いないハーフトーニング「フロイドスタインバーグ型誤差拡散法」

img_src = cv2.imread("data/img_A-3.bmp")
img_dst = np.empty_like(img_src)
#座標の大きさ
eight = img_src.shape[0]
width = img_src.shape[1]

for y in range(0,eight):
    for x in range(0,width):
        img_dst[y,x] = img_src[y,x]

for y in range(0,eight):
    for x in range(0,width):
        temp = float(img_src[y,x,0])
        if temp > 127:
            e = temp - 255
        else:
            e = temp 

        if 1 <= x < width - 1 and 1 <= y < eight-1:
            img_dst[y    ,x+1,0] = float(img_dst[y,x+1,0]) + 0.3125*e  
            img_dst[y+1,x-1,0] = float(img_dst[y+1,x-1,0]) + 0.1875*e
            img_dst[y+1,x   ,0] = float(img_dst[y+1,x,0]) + 0.3125*e  
            img_dst[y+1,x+1,0] = float(img_dst[y+1,x+1,0]) + 0.1875*e

for y in range(0,eight):
    for x in range(0,width):
        temp = img_dst[y,x,0]
        img_dst[y,x] = [temp,temp,temp]


#描画する
cv2.imshow("img_src",img_src)
cv2.imshow("img_dst",img_dst)

cv2.waitKey(0)
cv2.destroyAllWindows()

#ヒストグラム
fig = plt.figure()
ax1 = fig.add_subplot(211) #総行数,総列数、サブプロット番号
ax2 = fig.add_subplot(212)

color_list = ["gray"]
ax2.set_ylim(0,5000)
for i,j in enumerate(color_list):
    hist = cv2.calcHist([img_src],[i],None,[256],[0,256])
    ax1.plot(hist,color = j)

color_list = ["gray"]
ax2.set_ylim(0,5000)
for i,j in enumerate(color_list):
    hist = cv2.calcHist([img_dst],[i],None,[256],[0,256])
    ax2.plot(hist,color = j)

今回はうまくいかなかった

f:id:bitop:20180212062412p:plain

f:id:bitop:20180216131258p:plain

f:id:bitop:20180216131344p:plain

Interface2017年05月号新画像処理101を読む

A-3 濃淡を網目の2値パターンで表現する「ベイヤー型ハーフトーニング」

from random import random
img_src = cv2.imread("data/img_A-3.bmp")
img_dst = np.empty_like(img_src)
#座標の大きさ
eight = img_src.shape[0]
width = img_src.shape[1]
patt = np.array([[0,8,2,10],
                        [12,4,14,6],
                        [3,11,1,9],
                        [15,7,13,5]])

for y in range(0,eight-1,4):
    for x in range(0,width-1,4):
        for j in range(4):
            for i in range(4):
                if img_src[y+j,x+i,0] < patt[i,j] * 16 + 8:
                    img_dst[y+j,x+i] = [0,0,0]
                else:
                    img_dst[y+j,x+i] = [255,255,255]

#描画する
cv2.imshow("img_src",img_src)
cv2.imshow("img_dst",img_dst)

cv2.waitKey(0)
cv2.destroyAllWindows()

#ヒストグラム
fig = plt.figure()
ax1 = fig.add_subplot(211) #総行数,総列数、サブプロット番号
ax2 = fig.add_subplot(212)

color_list = ["gray"]
ax2.set_ylim(0,5000)
for i,j in enumerate(color_list):
    hist = cv2.calcHist([img_src],[i],None,[256],[0,256])
    ax1.plot(hist,color = j)

color_list = ["gray"]
ax2.set_ylim(0,5000)
for i,j in enumerate(color_list):
    hist = cv2.calcHist([img_dst],[i],None,[256],[0,256])
    ax2.plot(hist,color = j)

f:id:bitop:20180212062412p:plain

f:id:bitop:20180215055630p:plain

f:id:bitop:20180215055714p:plain