Как получить координаты светлых или темных пикселей? OpenCV

Я пытаюсь получить координаты белых n черных пикселей из двоичного изображения, чтобы я мог получить ROI изображения и изменить значения пикселей. Любая функция, которую я могу вызвать?

Это оригинальное изображение

После этого он будет пороговым с использованием метода OTSU. Результат: рисунок 8.7

Я хочу получить результат рисунка 8.8 из рисунка 8.7 (извините за изображение, я уже пытался повернуть его, но он все еще выглядит таким образом). Есть ли способ?

Вот ссылка на пороговое изображение. http://i.imgur.com/9EXmHN0.png

После этого я смогу получить рентабельность инвестиций.

0

Решение

Ну вот:

Разделите изображение на блоки / ячейки и вычислите соотношение / процентное соотношение белого / черного пикселя и раскрасьте весь блок в изображение маски в желаемый цвет.

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 — это отпечаток с пороговым значением, если вы используете исходное сканирование в качестве входного сигнала, вы должны пороговое значение вручную.

введите описание изображения здесь

выход:

маска для> 30% белого пикселя в блоке:

введите описание изображения здесь

комбинированная маска и вход (вход = пороговое значение здесь):

введите описание изображения здесь

4

Другие решения

Ты ищешь 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.
2

Вы должны использовать порог для этого. Увидеть http://docs.opencv.org/doc/tutorials/imgproc/threshold/threshold.html

Судя по всему, вам понадобится двоичный или двоичный код (инвертированный).

0
По вопросам рекламы [email protected]