我只是想在OpenCV的坐标系及其像素强度系统背后做一个解释。我正在使用for循环来查找屏幕上最密集的像素(我知道我可以使用minMaxLoc来找到它,但是,我的代码也将更改为也可以找到最左边的像素,因此需要此for循环)。
for (int i = 0; i < imgHight; i++) //Going through the height or Y axis.
{ // The height and width are equal the image is a square
for (int j = 0; j < imgWidth; j++) // Going through the width or X axis.
{
newInten = grayImg.at<uchar>(j, i); // This uses the X and Y to find a new point
HeadInten = grayImg.at<uchar>(Head); // This uses the stored XY as a comparassion
newIntenVal = newInten.val[0]; // This finds the intensity of the pixel at this point
if (newIntenVal > LowerBounds) //Compaired to lower bounds (80% of max pixel intensity)
{
if (newIntenVal > HeadIntenVal) // If the new intensity is higher than old then change head to new point and run again.
{
//cout << newInten << " " << HeadInten << " " << i << " " << j << endl;
Head = { j, i};
HeadIntenVal = HeadInten.val[0]; // Finds the intensity of pixel at stored head.
}
}
}
}
然后我在Head周围画一个圆圈,以在图片上显示其位置。问题是,当前当前绘制位置是随机的,但是当Head = {i,j}(X和Y取反)时,则绘制位置是期望的。关于为什么会发生这种情况有什么建议吗? 圆圈不正确: 正确的圈子:
问题在于尝试使用Head的点值再次找到该像素的强度,这给了我不同的结果,以后无法用于比较。
非常感谢您的帮助!
编辑:完整代码-对不起,有点混乱
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
double IBKG, IMAX, TC, LowerBounds; // IBKG is Image Background Level
Intensity, IMAX is Maximum Image Intensity, TC is comet theshold
Point IBKG_LOC, IMAX_LOC; // These are the respective locations on the
image, head is to find the head of the comet
Mat img = imread("Test1.png");
Mat grayImg;
int imgHight = img.rows;
int imgWidth = img.cols;
cout << imgHight << " " << imgWidth << endl;
cvtColor(img, grayImg, CV_RGB2GRAY);
minMaxLoc(grayImg, &IBKG, &IMAX, &IBKG_LOC, &IMAX_LOC);
cout << IMAX_LOC << endl;
TC = (IBKG + IMAX) / 2;
LowerBounds = IMAX * 0.8;
cout << LowerBounds << endl;
uint8_t newInten;
int maxX = 0, maxY = 0;
uint8_t grayMax = grayImg.at<uint8_t>(maxY, maxX);
for (int i = 0; i < imgHight; i++) //Going through the height or Y axis.
{ // The height and width are equal the image is a square
for (int j = 0; j < imgWidth; j++) // Going through the width or X axis.
{
uint8_t newInten = grayImg.at<uchar>(i,j); // This uses the X and Y to find a new point
if (newInten > LowerBounds) //Compaired to lower bounds (80% of max pixel intensity)
{
if (newInten > grayMax) // If the new intensity is higher than old then change head to new point and run again.
{
grayMax = newInten;
maxX = j;
maxY = i;
}
}
}
}
Point LeftSide;
bool leftSideFlag = false;
for (int i = maxX; i > 0; i--)
{
newInten = grayImg.at<uchar>(maxY, i);
if (!leftSideFlag)
{
if (newInten < TC)
{
LeftSide = { maxY, i};
leftSideFlag = true;
//i = 1;
}
}
}
int CircleRadius = maxX - LeftSide.x;
circle(img, Point(maxY, maxX), 10, Scalar(255, 255, 255));
cout << IBKG <<" " << IMAX << " " << IBKG_LOC << " " << IMAX_LOC << " " << TC << endl;
namedWindow("Image", WINDOW_NORMAL);
namedWindow("Gray Image", WINDOW_NORMAL);
imshow("Image", img);
imshow("Gray Image", grayImg);
waitKey(0);
return 0;
}
答案 0 :(得分:1)
Mat.at函数需要参数row,column顺序。 所以先是Y然后是X
int imgHight = grayImg.rows;
int imgWidth = grayImg.cols;
int maxX = 0, maxY = 0;
uint8_t grayMax = grayImg.at<uint8_t>(maxY,maxX);
for (int i = 0; i < imgHight; i++) //Going through the height or Y axis.
{ // The height and width are equal the image is a square
for (int j = 0; j < imgWidth; j++) // Going through the width or X axis.
{
uint8_t newInten = grayImg.at<uchar>(i, j); // This uses the X and Y to find a new point
if (newInten > grayMax)
{
grayMax = newInten;
maxX = j;
maxY = i;
}
}
}
还稍微更改了代码以使其更快。 虽然不是最快的选择。
答案 1 :(得分:1)
在添加了建议的修复程序之后,我将X和Y换成我通常期望用于绘制圆的方式,我还需要记住将maxX与Leftside.y进行比较。现在的结果符合预期。谢谢大家!