У меня есть изображение (показано ниже). Я хочу извлечь только часть розового цвета и удалить остальную часть изображения. У меня есть значение RGB, сохраненное в массиве. Есть ли способ, которым я могу использовать bitwise_and
на изображении и цвет, чтобы я мог выделить нужную часть в OpenCV?Как извлечь часть изображения с определенным цветом?
ответ
Bitwise_and не правильный метод для этого, так как это побитовое. Но для этой основной задачи есть, конечно, методы в OpenCv:
Если вы знаете точное значение, вы можете просто использовать метод CmpS. Если вы хотите найти все розовые цвета в определенном диапазоне, используйте метод InRangeS. По желанию сначала измените цветовое пространство изображения, например. если вы хотите указать свой диапазон в пространстве HSV.
С вашего зеленый цвет не является равномерным, но она колеблется от:
// in BGR color space
Scalar low(182, 204, 168);
Scalar high(187, 207, 172);
// in HSV color space
Scalar low(72, 43, 204);
Scalar high(72, 45, 207);
вы можете использовать функцию inRange. Вы можете настроить диапазоны в соответствии с цветом, который вам нужно сегментировать.
Обычно цветовое пространство HSV лучше подходит для задач сегментации на основе цвета, но в этом случае цветовое пространство BGR достаточно хорошее.
Этот код показывает, как получить бинарную маску нужного цвета и как скопировать только маску часть исходного изображения в цветовом пространстве BGR и HSV.
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
// Load image
Mat3b img = imread("path_to_image");
{
// BGR color space
// Setup ranges
Scalar low(182, 204, 168);
Scalar high(187, 207, 172);
// Get binary mask
Mat1b mask;
inRange(img, low, high, mask);
// Initialize result image (all black)
Mat3b res(img.rows, img.cols, Vec3b(0, 0, 0));
// Copy masked part to result image
img.copyTo(res, mask);
imshow("Mask from BGR", mask);
imshow("Result from BGR", res);
waitKey();
}
{
// HSV color space
// Convert to HSV
Mat3b hsv;
cvtColor(img, hsv, COLOR_BGR2HSV);
// Setup ranges
Scalar low(72, 43, 204);
Scalar high(72, 45, 207);
// Initialize result image (all black)
// Get binary mask
Mat1b mask;
inRange(hsv, low, high, mask);
// Initialize result image (all black)
Mat3b res(img.rows, img.cols, Vec3b(0, 0, 0));
// Copy masked part to result image
img.copyTo(res, mask);
imshow("Mask from HSV", mask);
imshow("Result from HSV", res);
waitKey();
}
return 0;
}
Пример маски:
Пример сегментированного изображения:
Это выглядит великолепно. Именно так я и хотел. Но, к сожалению, для меня я использую Opencv 2.1 и C ... поэтому я не могу использовать код. Я пытаюсь использовать эту логику в C. :( Еще одна вещь: я сохранил точный цвет сегмента (зеленый в этом случае) в массиве, поэтому могу ли я дать те же значения для скалярного высокого и низкого? –
@ AbhishekV.Pai 1) вы указываете тег C++, поэтому этот код является C++ по запросу. 2) Вы не указали, что у вас устаревшая версия OpenCV, поэтому я предположил, что это была последняя версия. Вы ** не можете ** попросить что-то, а затем изменить критерии. Кроме того, вы компилируете с помощью компилятора C++, а также код в вашем собственном ответе - C++, поэтому я не понимаю, как вы используете это в C. – Miki
Мне очень жаль, что я не был конкретным. Но я действительно хочу поблагодарить вас за вашу помощь. Я обновляю свою Opencv и Visual Studio и запускаю ваш код. Я использую visual studio 2009 для компиляции, поэтому я не знаю, почему эта конкретная ошибка отображается. –
Вы можете обеспечить нон сжатый файл (например, PNG)? Пожалуйста, не конвертируйте jpeg в png, но сохраните изображение прямо в png. jpeg вызывает артефакты сжатия, что делает эту задачу излишне сложной. – Miki
Я сохранил его в png. но как мне получить результат, который я желаю? –
Опубликовать png изображение пожалуйста – Miki