简体   繁体   English

如何获得亮或暗像素的坐标? OpenCV的

[英]How to get the coordinate of bright or dark pixels? OpenCV

I'm trying to get the coordinate of the white n black pixels from a binary image so that i can get the ROI of the image and alter the pixel values. 我正在尝试从二进制图像中获取白色n黑色像素的坐标,以便可以获取图像的ROI并更改像素值。 Any function that I can call? 我可以调用任何函数吗?

This is the original image 这是原始图像

After that it'll be thresholded using OTSU method. 之后,将使用OTSU方法对其进行阈值处理。 Result : Figure8.7 结果:图8.7

I wish to get the result of Figure 8.8 from Figure 8.7 (Sorry about the image, i tried to rotate it already but it still appears this way). 我希望从图8.7获得图8.8的结果(对图像感到抱歉,我已经尝试过旋转它,但是它仍然以这种方式出现)。 Is there any method? 有什么办法吗?

Here's the thresholded image link. 这是阈值图像链接。 http://i.imgur.com/9EXmHN0.png http://i.imgur.com/9EXmHN0.png

After that I'll be able to get my ROI. 之后,我将能够获得投资回报率。

Here you go: 干得好:

Subdivide the image into blocks/cells and compute the ratio/percentage of white/black pixel and color the whole block in a mask image in the desired color. 将图像细分为块/单元,并计算白色/黑色像素的比率/百分比,并以所需颜色对蒙版图像中的整个块进行着色。

int main()
{
// load your real image here
cv::Mat img = cv::imread("fingerprint.png", CV_LOAD_IMAGE_GRAYSCALE);


// after thresholding: all pixel 255 or 0
cv::Mat thres = img > 0;    // input image was thresholded already...
//cv::threshold(img,thres,58,255,CV_THRESH_OTSU);   // if original input, use your OTSU (remark: have to convert to grayscale first?)

cv::Mat mask = thres.clone();
mask = 100; // set it to gray to see at the end whether all blocks were performed and painted

//float minRatio = 0.5f;
float minRatio = 0.3f;
//float minRatio = 0.1f;    // ratio of white pixel within a block to accept as a filled block

// size of a single block:
cv::Size block(16,26);

// count pixel in each block and decide whether the block is white or black:
for(int j=0; j<img.rows; j+=block.height)
    for(int i=0; i<img.cols; i+=block.width)
    {
        // current block:
        cv::Rect currentBlock(i, j, block.width, block.height);

        // pixel counter
        unsigned int cWhite = 0;
        unsigned int cBlack = 0;
        // iterate through whole block and count pixels
        for(int y=currentBlock.y; y<currentBlock.y+currentBlock.height; ++y)
            for(int x=currentBlock.x; x<currentBlock.x+currentBlock.height; ++x)
            {
                // care for blocks that don't fit into the image. If known imagesize and block sizes fit exactly, this may be removed
                if((y < img.rows)&&(x < img.cols))
                {
                    if(thres.at<unsigned char>(y,x) == 255) cWhite++;
                    else cBlack++;
                }
            }

        // compute block color from ratio
        unsigned char blockColor = 0;
        if((float)cWhite/(float)(cBlack+cWhite) > minRatio) blockColor = 255;

        // same loop as before, but now fill the mask. maybe there are faster ways... don't know
        for(int y=currentBlock.y; y<currentBlock.y+currentBlock.height; ++y)
            for(int x=currentBlock.x; x<currentBlock.x+currentBlock.height; ++x)
            {
                if((y < img.rows)&&(x < img.cols))
                {
                    mask.at<unsigned char>(y,x) = blockColor;   // set mask block color
                }
            }
    }

// copy the image masked
cv::Mat combined;
img.copyTo(combined,mask);


// writing results to show you
cv::imwrite("fingerprintInput.png", thres);

cv::imshow("mask",mask);
cv::imwrite("fingerprintMask.png", mask);

cv::imshow("combined", combined);
cv::imwrite("fingerprintCombined.png", combined);


cv::waitKey(-1);
return 0;
}

input: input here is the thresholded fingerprint, if you use your original scan as the input, you have to threshold manually. 输入:此处输入的是阈值指纹,如果您使用原始扫描作为输入,则必须手动阈值。

在此处输入图片说明

output: 输出:

mask for > 30% white pixel in a block: 块中大于30%白色像素的蒙版:

在此处输入图片说明

combined mask and input (input = thresholded here): 组合的掩码和输入(此处输入=阈值):

在此处输入图片说明

You are looking for Mat::copyTo() and use the second image as the mask . 您正在寻找Mat::copyTo()并将第二张图像用作mask

C++: void Mat::copyTo(OutputArray m, InputArray mask) const

Parameters: 
    m – Destination matrix. If it does not have a proper size or type before the operation, it is reallocated.
    mask – Operation mask. Its non-zero elements indicate which matrix elements need to be copied.

You need to use thresholding for this. 您需要为此使用阈值。 See http://docs.opencv.org/doc/tutorials/imgproc/threshold/threshold.html 参见http://docs.opencv.org/doc/tutorials/imgproc/threshold/threshold.html

From the looks of it, you would need binary or binary (inverted). 从外观上看,您将需要二进制或二进制(取反)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM