c – 如何使用OpenCV检测白色斑点
作者:互联网
我画一幅画来测试:
而且我想知道我在黑色圆圈中有多少斑点,每个斑点的大小是多少(所有斑点都是〜白色).
例如,在这种情况下,我有12个点:
我知道如何找到白色像素,并且很容易从左侧验证序列:
int whitePixels = 0;
for (int i = 0; i < height; ++i)
{
uchar * pixel = image.ptr<uchar>(i);
for (int j = 0; j < width; ++j)
{
if (j>0 && pixel[j-1]==0) // to group pixels for one spot
whitePixels++;
}
}
但很明显,这段代码不够好(blob可以对角线等).
所以,底线,我需要帮助:我如何定义blob?
谢谢
解决方法:
以下代码查找所有白点的边界值(blob).
备注:如果我们可以假设白点真的是白色(即灰度图像中的值为255),则可以使用此片段.考虑将它放在某个类中以避免将不必要的params传递给Traverse函数.虽然它有效.这个想法是基于DFS.除了gryscaled图像,我们有id矩阵来分配和记住哪个像素属于哪个blob(具有相同id的所有像素属于同一个blob).
void Traverse(int xs, int ys, cv::Mat &ids,cv::Mat &image, int blobID, cv::Point &leftTop, cv::Point &rightBottom) {
std::stack<cv::Point> S;
S.push(cv::Point(xs,ys));
while (!S.empty()) {
cv::Point u = S.top();
S.pop();
int x = u.x;
int y = u.y;
if (image.at<unsigned char>(y,x) == 0 || ids.at<unsigned char>(y,x) > 0)
continue;
ids.at<unsigned char>(y,x) = blobID;
if (x < leftTop.x)
leftTop.x = x;
if (x > rightBottom.x)
rightBottom.x = x;
if (y < leftTop.y)
leftTop.y = y;
if (y > rightBottom.y)
rightBottom.y = y;
if (x > 0)
S.push(cv::Point(x-1,y));
if (x < ids.cols-1)
S.push(cv::Point(x+1,y));
if (y > 0)
S.push(cv::Point(x,y-1));
if (y < ids.rows-1)
S.push(cv::Point(x,y+1));
}
}
int FindBlobs(cv::Mat &image, std::vector<cv::Rect> &out, float minArea) {
cv::Mat ids = cv::Mat::zeros(image.rows, image.cols,CV_8UC1);
cv::Mat thresholded;
cv::cvtColor(image, thresholded, CV_RGB2GRAY);
const int thresholdLevel = 130;
cv::threshold(thresholded, thresholded, thresholdLevel, 255, CV_THRESH_BINARY);
int blobId = 1;
for (int x = 0;x<ids.cols;x++)
for (int y=0;y<ids.rows;y++){
if (thresholded.at<unsigned char>(y,x) > 0 && ids.at<unsigned char>(y,x) == 0) {
cv::Point leftTop(ids.cols-1, ids.rows-1), rightBottom(0,0);
Traverse(x,y,ids, thresholded,blobId++, leftTop, rightBottom);
cv::Rect r(leftTop, rightBottom);
if (r.area() > minArea)
out.push_back(r);
}
}
return blobId;
}
编辑:我修复了一个错误,降低了阈值水平,现在输出如下.我认为这是一个很好的起点.
EDIT2:我在Traverse()中摆脱了递归.在更大的图像递归引起Stackoverflow.
标签:object-detection,c,opencv,image-processing 来源: https://codeday.me/bug/20190830/1771647.html