OpenCV像素强度

时间:2018-07-18 13:48:03

标签: c++ opencv

我只是想在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取反)时,则绘制位置是期望的。关于为什么会发生这种情况有什么建议吗? 圆圈不正确:https://gyazo.com/bc7808c7a9de724a33a587f1524d10f5 正确的圈子:https://gyazo.com/560a460822a45d24c2dcbae31cd5c8d5

问题在于尝试使用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;

}

2 个答案:

答案 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进行比较。现在的结果符合预期。谢谢大家!