问题
I want to detect a specific pixel value (let's say 128 in a unsigned 8 bit 1-channel image) in a cv::Mat
image and replace the value of all the pixels with that specific value with another value (replacing each 128 with 120). Is there any efficient way of doing this? Or should I do the search and assertion operations pixel by pixel?
I started coding but could not completed. Here is the part of my code:
cv::Mat source;
unsigned oldValue = 128;
unsigned newValue = 120;
cv::Mat temp = (source == oldValue);
回答1:
You can use setTo
, using a mask:
Mat src;
// ... src is somehow initialized
int oldValue = 128;
int newValue = 120;
src.setTo(newValue, src == oldValue);
回答2:
not sure whether it is more efficient than .setTo
, but you could use a look-up-table (especially if you have multiple values you want to replace and you have to replace the same values in multiple images (e.g. in each image of a video stream)).
int main()
{
cv::Mat input = cv::imread("../inputData/Lenna.png");
cv::Mat gray;
cv::cvtColor(input,gray,CV_BGR2GRAY);
// prepare this once:
cv::Mat lookUpTable(1, 256, CV_8U);
uchar* p = lookUpTable.data;
for( int i = 0; i < 256; ++i)
{
p[i] = i;
}
// your modifications
p[128] = 120;
// now you can use LUT efficiently
cv::Mat result;
cv::LUT(gray, lookUpTable, result);
cv::imshow("result", result);
cv::imwrite("../outputData/LUT.png", result);
cv::waitKey(0);
return 0;
}
According to http://docs.opencv.org/doc/tutorials/core/how_to_scan_images/how_to_scan_images.html#the-core-function this is very efficient in special scenarios.
来源:https://stackoverflow.com/questions/32348302/opencv-replacing-specific-pixel-values-with-another-value