获取顶部和底部白色像素的坐标以绘制一条线
Obtaining coordinate of the top and bottom white pixels in order to draw a line
我在位图扩展中有以下二进制图像:
现在我想:
- 获取上下白色像素点坐标(蓝色标记)
- 画一条线(黄线)与这两个坐标相交(类似于下图)
我试过at
函数,image.at<uchar>(i,j)
但没有成功。如果有人能帮助我,我将不胜感激。提前致谢!
Mat image = imread("Before.bmp");
int i=1;
imshow("Before", image);
vector<Point> locations; // output, locations of non-zero pixels
cv::findNonZero(image, locations);
Point pnt = locations[i]; /Assertion error
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++) {
if (image.at<uchar>(i,j) == 255 ) {
cout << i << ", " << j << endl; //give wrong coordinate
}
}
}
//imshow("black", image);
//imwrite("blackie.bmp", image);
waitKey(0);
return(0);
您可以使用 cv::findNonZero
来查找任何 non-zero(即非黑色)像素的坐标。根据文档,这个函数要求输入是单通道图像,所以需要先转成灰度。
在下面的示例中,我假设白线从顶行一直延伸到底行,并且在图像的顶部和底部边缘恰好有两条白线(就像你的形象)。您可能希望将其扩展为更灵活。
示例代码
#include <opencv2/opencv.hpp>
int main(int argc, char *argv[])
{
cv::Mat image(cv::imread("foo.png"));
cv::Mat gray;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
std::vector<cv::Point> locations[2];
// Top points
cv::findNonZero(gray.row(0), locations[0]);
// Bottom points (need to offset Y since we take a single row ROI)
cv::findNonZero(gray.row(image.rows - 1), locations[1]);
for (auto& p : locations[1]) {
p.y += image.rows - 1;
}
// Validate our assumption of having exactly two points on both top as well as bottom row
if ((locations[0].size() != 2) && (locations[0].size() != 2)) {
std::cerr << "Unexpected input.\n";
return -1;
}
for (int i(0); i < 2; ++i) {
cv::line(image, locations[0][i], locations[1][i], cv::Scalar(0, 255, 255));
}
cv::imwrite("foo_out.png", image);
}
示例输出
我在位图扩展中有以下二进制图像:
现在我想:
- 获取上下白色像素点坐标(蓝色标记)
- 画一条线(黄线)与这两个坐标相交(类似于下图)
我试过at
函数,image.at<uchar>(i,j)
但没有成功。如果有人能帮助我,我将不胜感激。提前致谢!
Mat image = imread("Before.bmp");
int i=1;
imshow("Before", image);
vector<Point> locations; // output, locations of non-zero pixels
cv::findNonZero(image, locations);
Point pnt = locations[i]; /Assertion error
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++) {
if (image.at<uchar>(i,j) == 255 ) {
cout << i << ", " << j << endl; //give wrong coordinate
}
}
}
//imshow("black", image);
//imwrite("blackie.bmp", image);
waitKey(0);
return(0);
您可以使用 cv::findNonZero
来查找任何 non-zero(即非黑色)像素的坐标。根据文档,这个函数要求输入是单通道图像,所以需要先转成灰度。
在下面的示例中,我假设白线从顶行一直延伸到底行,并且在图像的顶部和底部边缘恰好有两条白线(就像你的形象)。您可能希望将其扩展为更灵活。
示例代码
#include <opencv2/opencv.hpp>
int main(int argc, char *argv[])
{
cv::Mat image(cv::imread("foo.png"));
cv::Mat gray;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
std::vector<cv::Point> locations[2];
// Top points
cv::findNonZero(gray.row(0), locations[0]);
// Bottom points (need to offset Y since we take a single row ROI)
cv::findNonZero(gray.row(image.rows - 1), locations[1]);
for (auto& p : locations[1]) {
p.y += image.rows - 1;
}
// Validate our assumption of having exactly two points on both top as well as bottom row
if ((locations[0].size() != 2) && (locations[0].size() != 2)) {
std::cerr << "Unexpected input.\n";
return -1;
}
for (int i(0); i < 2; ++i) {
cv::line(image, locations[0][i], locations[1][i], cv::Scalar(0, 255, 255));
}
cv::imwrite("foo_out.png", image);
}