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?
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?
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.
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>
//@link: http://answers.opencv.org/question/87979/all-points-above-a-line/
//@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.
Asked: 2016-02-18 09:45:50 -0600
Seen: 450 times
Last updated: Feb 20 '16
How to estimate the noiselevel of an image?
How to find a match between 2 shifted hue histograms?
Single Image Depth Map / Sharpness Map
How to match two images and find out mistakes
Remove buttons from their background so I can re-use button image
Image stitching from a live video stream
Which matcher is best for SURF?
Classification of object from a video/Image ( human, animals, others(cars etc.,))
Not efficient way:
use affine transform (rotation given by your line) to change axis