# All points above a line I have an image and a line bisecting that image (with a slope between -1.0 and 1.0). Is there an effective way to access all points above the line?

edit retag close merge delete

1

Not efficient way:

• iterate through the image
• test for the sign of the line equation

use affine transform (rotation given by your line) to change axis

Sort by » oldest newest most voted The image is stored row major, so you want to go down each row. The equation of a line is y=m*x+b, but we need to invert it. x = y/m-b/m.

if(m > 0)
{
for(int y = 0; y<MIN(b,rows); ++y)
{
for(int x = 0; x < MIN(cols, (y-b)/m); ++x)
{
//Do Stuff Here
}
}
}
else if(m == 0) //Trivial case
else
{
for(int y = 0; y<MIN(b, rows); ++y)
{
for(int x = MAX(0, (y-b)/m); x<cols; ++x)
{
//Do Stuff Here
}
}
}


Note: This assumes your equation is in image space, which has +y as the bottom of the image.

Can someone else double check this? I don't have a compiler handy.

more

Nice piece of code @Tetragramm !

I modified your code by "randomly" swapping the elements until it works as dealing with the 2 frame origins gave me some headaches and I didn't manage to make work your original code with the different line equations.

I also added my "brute force approach".

The result with your (modified) approach:

The result with pt1(20, 15), pt2(600, 385) in normal 2D frame: The result with pt1(50, 421), pt2(621, 77) in normal 2D frame: The result with pt1(0, 600), pt2(621, 77) in normal 2D frame: The result with pt1(0, -50), pt2(621, 253) in normal 2D frame: The corresponding code:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

//@author: Tetragramm
void drawPoints(cv::Mat &img, const double m, const double b)
{
//Optimal way
int rows = img.rows, cols = img.cols;
if(m > 0)
{
for(int y = 0; y < MAX(b,rows); ++y)
{
for(int x = MAX(0, (y-b)/m); x<cols; ++x)
{
//Do Stuff Here
img.at<cv::Vec3b>(y, x) = cv::Vec3b(255,0,0);
}
}
}
else if(m == 0) {
//Trivial case
}
else
{
for(int y = 0; y < MIN(b, rows); ++y)
{
for(int x = 0; x < MIN(cols, (y-b)/m); ++x)
{
//Do Stuff Here
img.at<cv::Vec3b>(y, x) = cv::Vec3b(255,0,0);
}
}
}
}

void calculateLineEquation(const cv::Point &pt1, const cv::Point &pt2, double &a, double &b)
{
a = (pt2.y - pt1.y) / (double) (pt2.x - pt1.x);
b = pt1.y - a*pt1.x;
}

void myDrawPoints(cv::Mat &img, const double a, const double b)
{
//BruteForce
for(int i = 0; i < img.rows; i++)
{
for(int j = 0; j < img.cols; j++)
{
double x = j, y = img.rows - i;
if(a * x + b - y > 0)
{
img.at<cv::Vec3b>(i, j) = cv::Vec3b(255,0,0);
}
else if(a * x + b - y < 0)
{
img.at<cv::Vec3b>(i, j) = cv::Vec3b(0,255,0);
}
}
}
}

int main()
{
//Coordinates in regular 2D frame
//int x1 = 20, x2 = 600;
//int y1 = 15, y2 = 385;
//int x1 = 50, x2 = 621;
//int y1 = 421, y2 = 77;
//int x1 = 0, x2 = 621;
//int y1 = 600, y2 = 77;
int x1 = 0, x2 = 621;
int y1 = -50, y2 = 253;
cv::Mat img1 = cv::Mat::zeros(480, 640, CV_8UC3), img2 = cv::Mat::zeros(480, 640, CV_8UC3),
img3 = cv::Mat::zeros(480, 640, CV_8UC3);
cv::Point pt1(x1, img1.rows - y1), pt2(x2, img1.rows - y2);

cv::line(img3, pt1, pt2, cv::Scalar(0,0,255), 1);

double a = 0.0;
double b = 0.0;

calculateLineEquation(pt1, pt2, a, b);
std::cout << "Line equation in image space, slope a=" << a << " ; ordinate at origin b=" << b << std::endl;
drawPoints(img1, a, b);

calculateLineEquation(cv::Point(x1,y1), cv::Point(x2,y2), a, b);
std::cout << "Regular 2D frame, slope a=" << a << " ; ordinate at origin b=" << b << std::endl;
myDrawPoints(img2, a, b);

cv::imshow("img1", img1);
cv::imwrite("points_above_line.png ...
more

Glad I could help. Thanks for doing that, I was busy and away from my normal computer yesterday.

Official site

GitHub

Wiki

Documentation