如何使用open cv将YUV422转化为MAT图像然后提取出转化后的Y通道值,计算提取Y图像的平均亮度值,将Y图像分割成64块,计算每块的平均亮度值,若每块的亮度值与整张图的平均亮度值比值超过某个阈值则为NG
时间: 2023-11-14 19:07:05 浏览: 67
首先,我们需要把YUV422的数据转化为OpenCV的MAT图像,代码如下:
```cpp
cv::Mat yuvImg(height, width, CV_8UC2, yuvData);
cv::Mat bgrImg(height, width, CV_8UC3);
cv::cvtColor(yuvImg, bgrImg, cv::COLOR_YUV2BGR_Y422);
```
其中,yuvData是一个指向存储YUV422数据的内存地址的指针,height和width分别是图像的高度和宽度。上面的代码使用OpenCV的cvtColor函数将YUV422图像转化为BGR格式的图像。
接下来,我们需要提取出转化后的图像的Y通道值,代码如下:
```cpp
std::vector<cv::Mat> channels;
cv::split(bgrImg, channels);
cv::Mat yImg = channels[0];
```
这里,我们使用split函数将BGR图像分离成三个通道,然后提取出Y通道。
然后,我们可以计算提取Y图像的平均亮度值,代码如下:
```cpp
double meanY = cv::mean(yImg)[0];
```
这里使用了OpenCV的mean函数计算Y通道的平均值。
接着,我们将Y图像分割成64块,代码如下:
```cpp
int blockSize = 8;
cv::Mat meanImg(yImg.size(), CV_32FC1, cv::Scalar::all(0));
for (int i = 0; i < yImg.rows; i += blockSize) {
for (int j = 0; j < yImg.cols; j += blockSize) {
int iEnd = std::min(i + blockSize, yImg.rows);
int jEnd = std::min(j + blockSize, yImg.cols);
cv::Rect roi(j, i, jEnd - j, iEnd - i);
cv::Scalar mean = cv::mean(yImg(roi));
meanImg(roi) = mean;
}
}
```
这里将Y图像分割成大小为8x8的块,使用两层循环遍历每个块,使用cv::mean函数计算块的平均值,将结果保存到meanImg中。
最后,我们可以判断每块的亮度值与整张图的平均亮度值比值是否超过某个阈值,代码如下:
```cpp
double threshold = 0.8;
cv::Mat ngImg = cv::Mat::zeros(yImg.size(), CV_8UC1);
for (int i = 0; i < yImg.rows; i += blockSize) {
for (int j = 0; j < yImg.cols; j += blockSize) {
int iEnd = std::min(i + blockSize, yImg.rows);
int jEnd = std::min(j + blockSize, yImg.cols);
cv::Rect roi(j, i, jEnd - j, iEnd - i);
cv::Scalar mean = cv::mean(meanImg(roi));
double ratio = mean[0] / meanY;
if (ratio < threshold) {
ngImg(roi) = 255; // 标记为NG
}
}
}
```
这里设定阈值为0.8,使用两层循环遍历每个块,计算块的平均值与整张图的平均值的比值,如果比值小于阈值,则将该块标记为NG,即将该块在ngImg中的相应区域赋值为255,表示该块为NG。
需要注意的是,上述代码中的yImg、meanImg和ngImg都是OpenCV的Mat类型,而不是指针或数组。
阅读全文