jashliao 用 VC++ 實現 fanfuhan OpenCV 教學010 ~ opencv-010-圖像像素值統計函數[minMaxLoc(一維陣列<灰階>最大最小值&位置座標) / meanStdDev(計算每一顏色通道平均值&標準差) / 普通圖像轉化為二值化圖像 / 彩色圖的相似顏色都標成相同區域,簡易分割圖片方式]

jashliao 用 VC++ 實現 fanfuhan OpenCV 教學010 ~ opencv-010-圖像像素值統計函數[minMaxLoc(一維陣列<灰階>最大最小值&位置座標) / meanStdDev(計算每一顏色通道平均值&標準差) / 普通圖像轉化為二值化圖像 / 彩色圖的相似顏色都標成相同區域,簡易分割圖片方式]

jashliao 用 VC++ 實現 fanfuhan OpenCV 教學010 ~ opencv-010-圖像像素值統計函數[minMaxLoc(一維陣列<灰階>最大最小值&位置座標) / meanStdDev(計算每一顏色通道平均值&標準差) / 普通圖像轉化為二值化圖像 / 彩色圖的相似顏色都標成相同區域,簡易分割圖片方式]


資料來源: https://fanfuhan.github.io/

https://fanfuhan.github.io/2019/03/25/opencv-010/


GITHUB:https://github.com/jash-git/fanfuhan_ML_OpenCV

https://github.com/jash-git/jashliao-implements-FANFUHAN-OPENCV-with-VC

★前言:


★主題:
     OPENCV提供計算圖像(陣列/數列)最大值、最小值、均值與標準方差的功能(統計數學),其功能函數條列如下:
        最大最小值minMaxLoc
        計算均值與標準方差meanStdDev

C++

// VC_FANFUHAN_OPENCV010.cpp : 定義主控台應用程式的進入點。
//
/*
// Debug | x32
通用屬性
| C/C++
|	| 一般
|		| 其他 Include 目錄 -> C:\opencv\build\include
|
| 連結器
| 	|一一般
|		|  其他程式庫目錄 -> C:\opencv\build\x64\vc15\lib
|
| 	|一輸入
|		| 其他相依性 -> opencv_world411d.lib;%(AdditionalDependencies)
// Releas | x64
組態屬性
| C/C++
|	| 一般
|		| 其他 Include 目錄 -> C:\opencv\build\include
|
| 連結器
| 	|一般
|		| 其他程式庫目錄 -> C:\opencv\build\x64\vc15\lib
|
| 	|一輸入
|		| 其他相依性 -> opencv_world411.lib;%(AdditionalDependencies)
*/
#include "stdafx.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

void pause()
{
	printf("Press Enter key to continue...");
	fgetc(stdin);
}
int main()
{
	Mat src_bgr = imread("../../images/test.png");
	Mat src_gray;

	cvtColor(src_bgr, src_gray, COLOR_BGR2GRAY);

	if (src_bgr.empty() || src_gray.empty())
	{
		cout << "could not load image.." << endl;
		pause();
		return -1;
	}
	else
	{
		imshow("input_bgr", src_bgr);
		imshow("input_gray", src_gray);

		// 计算灰度图像的最大最小值
		double minVal, maxVal;
		Point minLoc, maxLoc;//座標位置
		/*
		1  minMaxLoc尋找矩陣(一維陣列當作向量,用Mat定義) 中最小值和最大值的位置.
		2  參數若不需要,則置為NULL或者0,即可.
		3  minMaxLoc針對Mat和MatND的重載中 ,第5個參數是可選的(optional),不使用不傳遞即可.
		*/
		minMaxLoc(src_gray, &minVal, &maxVal, &minLoc, &maxLoc);//搜尋灰階影像中的最大與最小值
		cout << "paramenters of src_gray:" << endl;
		printf("min:%.2f, max:%.2f \n", minVal, maxVal);
		printf("min loc: (%d, %d) \n", minLoc.x, minLoc.y);
		printf("max loc: (%d, %d) \n", maxLoc.x, maxLoc.y);
		
		Mat mean_g, stddev_g;
		/*
		計算矩陣的均值和標準偏差。
		C++: void meanStdDev(InputArray src,OutputArray mean, OutputArray stddev, InputArray mask=noArray())
		C: void cvAvgSdv(constCvArr* arr, CvScalar* mean, CvScalar* std_dev, const CvArr* mask=NULL )
		Python: cv.AvgSdv(arr,mask=None) -> (mean, stdDev)
		parameter:
		src:輸入矩陣,這個矩陣應該是1-4通道的,這可以將計算結果存在Scalar_ ‘s中
		mean:輸出引數,計算均值
		stddev:輸出引數,計算標準差
		mask:可選引數
		*/
		meanStdDev(src_gray, mean_g, stddev_g);
		printf("gray channel mean:%.2f, stddev: %.2f \n\n", mean_g.at<double>(0, 0), stddev_g.at<double>(0, 0));
		for (int row = 0; row < src_bgr.rows; ++row) {
			for (int col = 0; col < src_bgr.cols; ++col) {
				Vec3b bgr = src_gray.at<Vec3b>(row, col);
				bgr[0] = bgr[0] < mean_g.at<double>(0, 0) ? 0 : 255;
				src_gray.at<Vec3b>(row, col) = bgr;
			}
		}
		imshow("gray_binary", src_gray);

		// 普通图像转二值图像 [彩色二值化圖]
		Mat mean, stddev;
		meanStdDev(src_bgr, mean, stddev);
		cout << "paramenters of src_bgr:" << endl;
		printf("blue channel mean:%.2f, stddev: %.2f \n", mean.at<double>(0, 0), stddev.at<double>(0, 0));
		printf("green channel mean:%.2f, stddev: %.2f \n", mean.at<double>(1, 0), stddev.at<double>(1, 0));
		printf("red channel mean:%.2f, stddev: %.2f \n", mean.at<double>(2, 0), stddev.at<double>(2, 0));
		for (int row = 0; row < src_bgr.rows; ++row) {
			for (int col = 0; col < src_bgr.cols; ++col) {
				Vec3b bgr = src_bgr.at<Vec3b>(row, col);
				bgr[0] = bgr[0] < mean.at<double>(0, 0) ? 0 : 255;
				bgr[1] = bgr[1] < mean.at<double>(1, 0) ? 0 : 255;
				bgr[2] = bgr[2] < mean.at<double>(2, 0) ? 0 : 255;
				src_bgr.at<Vec3b>(row, col) = bgr;
			}
		}
		imshow("bgr_binary", src_bgr);

		waitKey(0);
	}

	return 0;
}


Python

import cv2 as cv
import numpy as np

src = cv.imread("../images/test.png", cv.IMREAD_GRAYSCALE)
cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
cv.imshow("input", src)

min, max, minLoc, maxLoc = cv.minMaxLoc(src)
print("min: %.2f, max: %.2f"% (min, max))
print("min loc: ", minLoc)
print("max loc: ", maxLoc)

means, stddev = cv.meanStdDev(src)
print("mean: %.2f, stddev: %.2f"% (means, stddev))
src[np.where(src < means)] = 0
src[np.where(src > means)] = 255
cv.imshow("binary", src)

cv.waitKey(0)
cv.destroyAllWindows()


★結果圖:



★延伸說明/重點回顧:

    透過OPENCV提供計算圖像(陣列/數列)最大值、最小值、均值與標準方差的功能(統計數學),可以讓我們更有效率且系統化知道圖像相關資訊

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *