如何在C++版OpenCV中实现Python的掩码提取所有像素功能
在C++ OpenCV中提取掩码下的所有像素
要实现Python中通过掩码提取所有符合条件像素的功能,你可以借助OpenCV的findNonZero函数定位掩码中的有效位置,再遍历这些位置收集像素值,结合reshape还能调整结果结构,完全匹配Python的输出形式。
灰度图场景示例
#include <opencv2/opencv.hpp> #include <vector> using namespace cv; using namespace std; int main() { // 读取灰度图像 Mat src_img = imread("xxx.jpg", IMREAD_GRAYSCALE); if (src_img.empty()) return -1; // 生成掩码:像素值大于50的区域 Mat mask; compare(src_img, Scalar(50), mask, CMP_GT); // 获取掩码中非零像素的坐标 vector<Point> locations; findNonZero(mask, locations); // 创建存储结果的Mat,存储所有符合条件的像素 Mat fetch(locations.size(), 1, src_img.type()); for (size_t i = 0; i < locations.size(); ++i) { fetch.at<uchar>(i) = src_img.at<uchar>(locations[i]); } // 可选:将结果转为N×1的一维结构,和Python输出完全对齐 Mat fetch_reshaped = fetch.reshape(1); return 0; }
彩色图场景示例
如果是彩色图,需要先确保每个通道的像素值都满足条件,再提取像素:
#include <opencv2/opencv.hpp> #include <vector> using namespace cv; using namespace std; int main() { // 读取彩色图像 Mat src_img = imread("xxx.jpg"); if (src_img.empty()) return -1; // 生成掩码:每个通道像素值都大于50 vector<Mat> channels; split(src_img, channels); Mat mask; // 逐通道比较后取交集 compare(channels[0], Scalar(50), mask, CMP_GT); Mat temp; compare(channels[1], Scalar(50), temp, CMP_GT); bitwise_and(mask, temp, mask); compare(channels[2], Scalar(50), temp, CMP_GT); bitwise_and(mask, temp, mask); // 获取掩码中非零像素的坐标 vector<Point> locations; findNonZero(mask, locations); // 存储所有符合条件的彩色像素 Mat fetch(locations.size(), 1, src_img.type()); for (size_t i = 0; i < locations.size(); ++i) { fetch.at<Vec3b>(i) = src_img.at<Vec3b>(locations[i]); } // 可选:转为N×3的二维结构,和Python中src_img[mask]的输出结构一致 Mat fetch_reshaped = fetch.reshape(src_img.channels()); return 0; }
说明
findNonZero会找出掩码中所有非零(即符合条件)的像素坐标,是实现该功能的核心。- 最终的
fetch_reshaped结构和Python中src_img[mask]返回的ndarray完全对应:灰度图是N×1的一维数组,彩色图是N×3的二维数组,每个元素对应一个像素的通道值。
内容的提问来源于stack exchange,提问作者Mactarvish
相关产品推荐
相关产品推荐

