如何使用 OpenCV 对图像中的像素组进行分组和突出显示?
How to group and highlight group of pixels in an image using OpenCV?
在对图像进行错误级别分析的过程中,我想使用OpenCV突出显示像素变化(仅单幅图像而不是差异)。我知道输出图像的像素级值,但不确定将它们组合在一起并为其分配形状的方法(下面的示例使用形状指定像素变化)。我想知道我是否可以检测到具有较亮像素的圆并将它们分组并为像素添加分组形状
输入图像:
结果图片:
如果我没理解错的话,你想在新图像中突出显示输入图像和输出图像之间的差异。为此,您可以使用 Image Quality Assessment: From Error Visibility to Structural Similarity. This method is already implemented in the scikit-image 图像处理库中引入的 结构相似性指数 (SSIM) 来采用定量方法来确定图像之间的确切差异。您可以安装 scikit-image
和 pip install scikit-image
。
skimage.measure.compare_ssim()
函数 returns 一个 score
和一个 diff
图像。 score
表示两幅输入图像之间的结构相似性指数,可以落在[-1,1]范围内,值越接近1代表相似度越高。但是由于您只对两个图像的不同之处感兴趣,因此 diff
图像将是我们关注的重点。具体来说,diff
图像包含具有更多视差的较暗区域的实际图像差异。较大的差异区域以黑色突出显示,而较小的差异以灰色突出显示。这是 diff
图片
如果仔细观察,可能是由于 .jpg
有损压缩造成的灰色噪声区域。因此,为了获得更清晰的结果,我们执行形态学操作来平滑图像。如果图像使用 .png
等无损图像压缩格式,我们将获得更清晰的结果。清理图像后,我们用绿色突出显示差异
from skimage.measure import compare_ssim
import numpy as np
import cv2
# Load images and convert to grayscale
image1 = cv2.imread('1.jpg')
image2 = cv2.imread('2.jpg')
image1_gray = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
image2_gray = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
# Compute SSIM between two images
(score, diff) = compare_ssim(image1_gray, image2_gray, full=True)
# The diff image contains the actual image differences between the two images
# and is represented as a floating point data type in the range [0,1]
# so we must convert the array to 8-bit unsigned integers in the range
# [0,255] before we can use it with OpenCV
diff = 255 - (diff * 255).astype("uint8")
cv2.imwrite('original_diff.png',diff)
# Perform morphological operations
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(diff, cv2.MORPH_OPEN, kernel, iterations=1)
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel, iterations=1)
diff = cv2.merge([close,close,close])
# Color difference pixels
diff[np.where((diff > [10,10,50]).all(axis=2))] = [36,255,12]
cv2.imwrite('diff.png',diff)
我认为最好的方法是简单地对图像进行阈值处理并应用形态变换。
我得到了以下结果。
阈值+形态:
Select最大分量:
使用此代码:
cv::Mat result;
cv::Mat img = cv::imread("fOTmh.jpg");
//-- gray & smooth image
cv::cvtColor(img, result, cv::COLOR_BGR2GRAY);
cv::blur(result, result, cv::Size(5,5));
//-- threashold with max value of the image and smooth again!
double min, max;
cv::minMaxLoc(result, &min, &max);
cv::threshold(result, result, 0.3*max, 255, cv::THRESH_BINARY);
cv::medianBlur(result, result, 7);
//-- apply Morphological Transformations
cv::Mat se = getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(11, 11));
cv::morphologyEx(result, result, cv::MORPH_DILATE, se);
cv::morphologyEx(result, result, cv::MORPH_CLOSE, se);
//-- find the largest component
vector<vector<cv::Point> > contours;
vector<cv::Vec4i> hierarchy;
cv::findContours(result, contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);
vector<cv::Point> *l = nullptr;
for(auto &&c: contours){
if (l==nullptr || l->size()< c.size())
l = &c;
}
//-- expand and plot Rect around the largest component
cv::Rect r = boundingRect(*l);
r.x -=10;
r.y -=10;
r.width +=20;
r.height +=20;
cv::rectangle(img, r, cv::Scalar::all(255), 3);
//-- result
cv::resize(img, img, cv::Size(), 0.25, 0.25);
cv::imshow("result", img);
Python代码:
import cv2 as cv
img = cv.imread("ELA_Final.jpg")
result = cv.cvtColor(img, cv.COLOR_BGR2GRAY);
result = cv.blur(result, (5,5));
minVal, maxVal, minLoc, maxLoc = cv.minMaxLoc(result)
ret,result = cv.threshold(result, 0.3*maxVal, 255, cv.THRESH_BINARY)
median = cv.medianBlur(result, 7)
se = cv.getStructuringElement(cv.MORPH_ELLIPSE,(11, 11));
result = cv.morphologyEx(result, cv.MORPH_DILATE, se);
result = cv.morphologyEx(result, cv.MORPH_CLOSE, se);
_,contours, hierarchy = cv.findContours(result,cv.RETR_LIST, cv.CHAIN_APPROX_NONE)
x = []
for eachCOntor in contours:
x.append(len(eachCOntor))
m = max(x)
p = [i for i, j in enumerate(x) if j == m]
color = (255, 0, 0)
x, y, w, h = cv.boundingRect(contours[p[0]])
x -=10
y -=10
w +=20
h +=20
cv.rectangle(img, (x,y),(x+w,y+h),color, 3)
img = cv.resize( img,( 1500, 700), interpolation = cv.INTER_AREA)
cv.imshow("result", img)
cv.waitKey(0)
在对图像进行错误级别分析的过程中,我想使用OpenCV突出显示像素变化(仅单幅图像而不是差异)。我知道输出图像的像素级值,但不确定将它们组合在一起并为其分配形状的方法(下面的示例使用形状指定像素变化)。我想知道我是否可以检测到具有较亮像素的圆并将它们分组并为像素添加分组形状
输入图像:
结果图片:
如果我没理解错的话,你想在新图像中突出显示输入图像和输出图像之间的差异。为此,您可以使用 Image Quality Assessment: From Error Visibility to Structural Similarity. This method is already implemented in the scikit-image 图像处理库中引入的 结构相似性指数 (SSIM) 来采用定量方法来确定图像之间的确切差异。您可以安装 scikit-image
和 pip install scikit-image
。
skimage.measure.compare_ssim()
函数 returns 一个 score
和一个 diff
图像。 score
表示两幅输入图像之间的结构相似性指数,可以落在[-1,1]范围内,值越接近1代表相似度越高。但是由于您只对两个图像的不同之处感兴趣,因此 diff
图像将是我们关注的重点。具体来说,diff
图像包含具有更多视差的较暗区域的实际图像差异。较大的差异区域以黑色突出显示,而较小的差异以灰色突出显示。这是 diff
图片
如果仔细观察,可能是由于 .jpg
有损压缩造成的灰色噪声区域。因此,为了获得更清晰的结果,我们执行形态学操作来平滑图像。如果图像使用 .png
等无损图像压缩格式,我们将获得更清晰的结果。清理图像后,我们用绿色突出显示差异
from skimage.measure import compare_ssim
import numpy as np
import cv2
# Load images and convert to grayscale
image1 = cv2.imread('1.jpg')
image2 = cv2.imread('2.jpg')
image1_gray = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
image2_gray = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
# Compute SSIM between two images
(score, diff) = compare_ssim(image1_gray, image2_gray, full=True)
# The diff image contains the actual image differences between the two images
# and is represented as a floating point data type in the range [0,1]
# so we must convert the array to 8-bit unsigned integers in the range
# [0,255] before we can use it with OpenCV
diff = 255 - (diff * 255).astype("uint8")
cv2.imwrite('original_diff.png',diff)
# Perform morphological operations
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(diff, cv2.MORPH_OPEN, kernel, iterations=1)
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel, iterations=1)
diff = cv2.merge([close,close,close])
# Color difference pixels
diff[np.where((diff > [10,10,50]).all(axis=2))] = [36,255,12]
cv2.imwrite('diff.png',diff)
我认为最好的方法是简单地对图像进行阈值处理并应用形态变换。
我得到了以下结果。
阈值+形态:
Select最大分量:
使用此代码:
cv::Mat result;
cv::Mat img = cv::imread("fOTmh.jpg");
//-- gray & smooth image
cv::cvtColor(img, result, cv::COLOR_BGR2GRAY);
cv::blur(result, result, cv::Size(5,5));
//-- threashold with max value of the image and smooth again!
double min, max;
cv::minMaxLoc(result, &min, &max);
cv::threshold(result, result, 0.3*max, 255, cv::THRESH_BINARY);
cv::medianBlur(result, result, 7);
//-- apply Morphological Transformations
cv::Mat se = getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(11, 11));
cv::morphologyEx(result, result, cv::MORPH_DILATE, se);
cv::morphologyEx(result, result, cv::MORPH_CLOSE, se);
//-- find the largest component
vector<vector<cv::Point> > contours;
vector<cv::Vec4i> hierarchy;
cv::findContours(result, contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);
vector<cv::Point> *l = nullptr;
for(auto &&c: contours){
if (l==nullptr || l->size()< c.size())
l = &c;
}
//-- expand and plot Rect around the largest component
cv::Rect r = boundingRect(*l);
r.x -=10;
r.y -=10;
r.width +=20;
r.height +=20;
cv::rectangle(img, r, cv::Scalar::all(255), 3);
//-- result
cv::resize(img, img, cv::Size(), 0.25, 0.25);
cv::imshow("result", img);
Python代码:
import cv2 as cv
img = cv.imread("ELA_Final.jpg")
result = cv.cvtColor(img, cv.COLOR_BGR2GRAY);
result = cv.blur(result, (5,5));
minVal, maxVal, minLoc, maxLoc = cv.minMaxLoc(result)
ret,result = cv.threshold(result, 0.3*maxVal, 255, cv.THRESH_BINARY)
median = cv.medianBlur(result, 7)
se = cv.getStructuringElement(cv.MORPH_ELLIPSE,(11, 11));
result = cv.morphologyEx(result, cv.MORPH_DILATE, se);
result = cv.morphologyEx(result, cv.MORPH_CLOSE, se);
_,contours, hierarchy = cv.findContours(result,cv.RETR_LIST, cv.CHAIN_APPROX_NONE)
x = []
for eachCOntor in contours:
x.append(len(eachCOntor))
m = max(x)
p = [i for i, j in enumerate(x) if j == m]
color = (255, 0, 0)
x, y, w, h = cv.boundingRect(contours[p[0]])
x -=10
y -=10
w +=20
h +=20
cv.rectangle(img, (x,y),(x+w,y+h),color, 3)
img = cv.resize( img,( 1500, 700), interpolation = cv.INTER_AREA)
cv.imshow("result", img)
cv.waitKey(0)