[英]OpenCV C++ - How can I replace the value of each pixel with the average value of the grayscale in a 3x3 neighborhood?
我是 OpenCV(在 C++ 中)和圖像處理的新手。 我想,給定一個灰度圖像來替換每個像素的值,計算 3x3 鄰域中灰度的平均值。
首先我打開圖片
Mat img = imread(samples::findFile(argv[1]), IMREAD_GRAYSCALE);
// Example of image
[4 3 9 1,
2 9 8 0,
3 5 2 1,
7 5 8 3]
為了獲得角的 3x3 最接近像素的平均值(左上角、右上角、左下角和右下角),我對圖像進行了填充:1x1x1x1 恆定邊框
Mat imgPadding;
copyMakeBorder(img, imgPadding, 1,1,1,1, BORDER_CONSTANT, Scalar(0));
// Padding example
[0 0 0 0 0 0,
0 4 3 9 1 0,
0 2 9 8 0 0,
0 3 5 2 1 0,
0 7 5 8 3 0,
0 0 0 0 0 0]
現在我在使用 output 圖像時遇到了一些問題。 我嘗試了各種方式,但沒有辦法讓我找到解決方案。 我試過這個,使用mean() function來獲得通過Rect() 方法得到的第 i,j-th 3x3 矩陣的平均灰度值。 for 循環從第一個非填充像素開始,到最后一個非填充像素結束。
Mat imgAvg = Mat::zeros(img.rows, img.cols, img.type());
// initialization of the output Mat object with same input size and type
for (int i = 1; i < imgAvg.rows; i++)
for (int j = 1; j < imgAvg.cols; j++)
imgAvg.at<Scalar>(Point(j - 1, i - 1)) = mean(imgPadding(Rect(j - 1, i - 1, 3, 3)));
但我得到了這個運行時錯誤
main: malloc.c:2379: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
我也嘗試隨機減少范圍
for (int i = 1; i < imgAvg.rows - 35; i++)
for (int j = 1; j < imgAvg.cols - 35; j++)
imgAvg.at<Scalar>(Point(j - 1, i - 1)) = mean(imgPadding(Rect(j - 1, i - 1, 3, 3)));
我得到了這個奇怪的 output:截圖
提前致謝!
編輯:謝謝大家的回答,我還不知道blur()
function。 這樣我導入圖像並簡單地調用模糊 function
Mat img = imread(samples::findFile(argv[1]), IMREAD_GRAYSCALE);
Mat imgAvg = Mat::zeros(img.rows, img.cols, img.type());
blur(img, imgAvg, Size(3, 3));
但是由於我仍然是初學者,並且我認為分配給我的練習的目的是編寫“手工”代碼,因此我也嘗試了這個可行的解決方案
for (int i = 1; i <= imgAvg.rows; i++)
for (int j = 1; j <= imgAvg.cols; j++)
imgAvg.at<uint8_t>(Point(j - 1, i - 1)) = mean(imgPadding(Rect(j - 1, i - 1, 3, 3)))[0];
只需對圖像應用平滑過濾器 - imgproc
模塊中的blur
function 應該可以滿足您的需要。 文檔中有一個很好的例子: https://docs.opencv.org/3.4/dc/dd3/tutorial_gausian_median_blur_bilateral_filter.ZFC35FDC70D5FC69D2698Z83A82EC
在這種情況下,您需要的 arguments 是圖像 ( img
)、目標圖像 ( dst
) 和 kernel 大小 ( ksize
),在這種情況下為 3:
src = ...
Mat dst = Mat::zeros( src.size(), src.type() )
blur( src, dst, Size( 3, 3 ))
手動平滑不會像以前那樣高效,而且更容易出錯。
祝你好運!
您要做的就是圖像處理中的“框過濾”。 在 OpenCV 你做:
cv::blur(src_img,
dest_img, // same shape and type as src, cannot be src
cv::Size(3, 3)) // use a kernel of size 3x3
默認填充是反映邊界像素,不會扭曲圖像統計信息。 如果您喜歡不同的邊框模式,請參閱文檔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.