查找兩張圖像差異的地方並標記 python版&c++版

python版已驗證代碼參考: 

# -*- coding: utf-8 -*-
from skimage.metrics import structural_similarity
import imutils
import cv2
# 加載兩張圖片並將他們轉換爲灰度
imageA = cv2.imread(r"1.jpg")
imageB = cv2.imread(r"2.jpg")

grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)

# 計算兩個灰度圖像之間的結構相似度指數
(score,diff) = structural_similarity(grayA,grayB,full = True)
diff = (diff *255).astype("uint8")
print("SSIM:{}".format(score))

# 找到不同點的輪廓以致於我們可以在被標識爲“不同”的區域周圍放置矩形
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]

# 找到一系列區域,在區域周圍放置矩形
for c in cnts:
    (x,y,w,h) = cv2.boundingRect(c)
    cv2.rectangle(imageA,(x,y),(x+w,y+h),(0,255,0),2)
    cv2.rectangle(imageB,(x,y),(x+w,y+h),(0,255,0),2)

# 用cv2.imshow 展現最終對比之後的圖片, cv2.imwrite 保存最終的結果圖片
cv2.imshow("Modified", imageB)
cv2.imwrite(r"result.bmp", imageB)
cv2.waitKey(0)

運行結果:

 

缺點:不適合用於工業的缺陷檢測,僅僅適用於相同尺寸的圖片

運行結果:

c++版代碼參考:

void imageSubtract(Mat &image1, Mat &image2)
{
	if ((image1.rows != image2.rows) || (image1.cols != image2.cols))
	{
		if (image1.rows > image2.rows)
		{
			resize(image1, image1, image2.size(), 0, 0, INTER_LINEAR);
		}
		else if (image1.rows < image2.rows)
		{
			resize(image2, image2, image1.size(), 0, 0, INTER_LINEAR);
		}
	}

	Mat image1_gary, image2_gary;
	if (image1.channels() != 1)
	{
		cvtColor(image1, image1_gary, COLOR_BGR2GRAY);
	}
	if (image2.channels() != 1)
	{
		cvtColor(image2, image2_gary, COLOR_BGR2GRAY);
	}

	Mat frameDifference, absFrameDifferece;
	Mat previousGrayFrame = image2_gary.clone();
	//圖1減圖2
	subtract(image1_gary, image2_gary, frameDifference, Mat(), CV_16SC1);

	//取絕對值
	absFrameDifferece = abs(frameDifference);

	//位深的改變
	absFrameDifferece.convertTo(absFrameDifferece, CV_8UC1, 1, 0);
	imshow("absFrameDifferece", absFrameDifferece);
	Mat segmentation;
	
	//閾值處理(這一步很關鍵,要調好二值化的值)
	threshold(absFrameDifferece, segmentation,100, 255, THRESH_BINARY);

	//中值濾波
	medianBlur(segmentation, segmentation, 3);

	//形態學處理(開閉運算)
	//形態學處理用到的算子
	Mat morphologyKernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
	morphologyEx(segmentation, segmentation, MORPH_CLOSE, morphologyKernel, Point(-1, -1), 2, BORDER_REPLICATE);

	//顯示二值化圖片
	imshow("segmentation", segmentation);

	//找邊界
	vector< vector<Point> > contours;
	vector<Vec4i> hierarchy;
	findContours(segmentation, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));//CV_RETR_TREE
	vector< vector<Point> > contours_poly(contours.size());

	vector<Rect> boundRect;
	boundRect.clear();

	for (int index = 0; index < contours.size(); index++)
	{
		approxPolyDP(Mat(contours[index]), contours_poly[index], 3, true);
		Rect rect = boundingRect(Mat(contours_poly[index]));
		rectangle(image2, rect, Scalar(0, 255, 0), 2);
	}
	imshow("效果圖", image2);
}

參考鏈接:

https://blog.csdn.net/matt45m/article/details/89294950

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章