ぱそきいろのIT日記

ぱそきいろがITに関する記事を書いていきます。

プログラミングで間違い探しをしてみた話

こんにちは!

ぱそきいろです!

 

今日はプログラミングを使って遊んでみたいと思います。

タイトルの通り、プログラミングで間違い探しをしてみました!

(Qiitaの方にも挙げているので良かったらみてください)
qiita.com


かなりの精度で間違い探しをできているので見てください!

まずは問題の画像です。

f:id:takabsk55:20190317001850j:plain
f:id:takabsk55:20190317001701j:plain
 
間違いが7つありますが、分かりますか?笑

正解は。。。

f:id:takabsk55:20190317002538j:plain

1 雲の大きさ
2 時計の時間
3 鳥の位置
4 女の子の髪型
5 女の子の髪型2
6 蝶々の向き
7 チューリップの草の形

そこまで難しくないですね。
人間にとっては簡単なのですが、これをプログラミングに解かせてみると
どうなるのでしょうか?

使ったのは物としては
MacBooc Air
Python 3.6
OpenCV 3.4
Matlab 2.1.2
こんな感じです!

やった事としては、
1.画像の差分を取る
2.画像を10×10の領域に分割
3.分割した領域のうち、差分が大きい場所をもとにヒートマップを作成
4.ヒートマップを元の画像に重ねる

文章にするとこんな感じです。

ではこれでできた結果を見てみましょう!

f:id:takabsk55:20190317005050j:plain

大体合ってますね!
ただ、時計の間違いだけ見つけれませんでした。。。

画像の差分を取っているので、時計の針みたいな線の間違いには弱いみたいです。。。

ただ、それ以外は綺麗に見つけれてますね!
嬉しいです!

最後にソースコードを載せておきます。
分かりにくかったり、質問があればコメントお願いします。

以上です!

import cv2

import matplotlib

matplotlib.use("Agg")
from pylab import *


PATH="/Users/takahiro/blog/machigai"

def main():
    # 元画像
    img0 = cv2.imread("pic1.jpg")
    #最新画像
    img1 = cv2.imread("pic2.jpg")

    gray0=cv2.cvtColor(img0,cv2.COLOR_RGB2GRAY)
    gray1=cv2.cvtColor(img1,cv2.COLOR_RGB2GRAY)

    cv2.imwrite("gray0.jpg",gray0)
    cv2.imwrite("gray1.jpg",gray1)

    diffpic=diff(gray0,gray1)
    cv2.imwrite("diff2.jpg",diffpic)

    heatdata=mkheatdata(diffpic)
    heatdata=np.reshape(heatdata,[100])
    heatindex=np.argsort(heatdata)[::-1]
    heatdata*=0
    for i in range(10):
        heatdata[heatindex[i]]=1
    heatdata=np.reshape(heatdata,[10,10])
    heatmap(heatdata)

    result = overray(img1)

    cv2.imwrite("result.jpg",result)

def Quantization(img):
    # 画像の量子化
    Z = img.reshape((-1, 3))

    # convert to np.float32
    Z = np.float32(Z)

    # define criteria, number of clusters(K) and apply kmeans()
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
    K = 4
    ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)

    # Now convert back into uint8, and make original image
    center = np.uint8(center)
    res = center[label.flatten()]
    res2 = res.reshape((img.shape))
    return res2

def diff(img0,img1):

    # フレームの絶対差分
    diff = cv2.absdiff(img0, img1)
    return diff

def heatmap(heatdata):
    fig,ax=plt.subplots()
    fig=plt.figure(figsize=(53,69.8),dpi=10)
    ax.tick_params(labelbottom="off", bottom="off")  # x軸の削除
    ax.tick_params(labelleft="off", left="off")  # y軸の削除
    ax.set_xticklabels([])
    box("off")  # 枠線の削除
    fig.subplots_adjust(left=0,bottom=0,right= 1,top=1)

    plt.pcolor(heatdata,cmap=plt.cm.Reds)
    plt.savefig('heatmap.png')

def mkheatdata(img):
    N=10
    M=10
    y=int(np.shape(img)[1]/N)
    x=int(np.shape(img)[0]/M)
    array=np.zeros((N,M))
    cv2.imwrite("img.jpg",img)
    for i in range(np.shape(img)[0]):
        for j in range(np.shape(img)[1]):
            if img[i][j]<70:
                img[i][j]=0
    cv2.imwrite("dif2.jpg",img)
    for n in range(N):
        for m in range(M):
            array[n][m]=np.sum(img[x*n:x*(n+1)-1,y*m:y*(m+1)-1])
    array=array[::-1][::1]
    return array

def overray(img):
    heatpic = cv2.imread("heatmap.png")

    result = cv2.addWeighted(img, 0.6, heatpic, 0.4,1)
    return result


def draw_heatmap(x, y):
    heatmap, xedges, yedges = np.histogram2d(x, y, bins=50)
    extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]

    plt.figure()
    plt.imshow(heatmap, extent=extent)
    plt.show()
    plt.savefig('image.png')


if __name__ == "__main__":
    main()