Я пытаюсь умножить два изображения разных моделей, в моем случае HSV и YCRCB.
Я получаю «вектор вне связанной ошибки» каждый раз.
Я проверил размеры умножаемых входных изображений, количество строк и столбцов. Я знаю, что значение превышает 255.
Я пытался реализовать этот метод opencv — умножение изображений, но код имеет путь ко многим MAT, которые должны быть инициализированы. Это также заставляет меня задать вопрос, можно ли умножать изображения с более чем одним каналом. Также пробовал прямое умножение, и оно не работает, поэтому пробовал умножать каналы мудро. Чтобы упростить процесс, я использовал метод loop, но затем произошла ошибка.
Краткая сводка о коде и причине его выполнения: я использую его для определения скина, но хочу еще больше уменьшить шум. Я думаю, что это можно сделать, умножив 2 выходных изображения, сгенерированных пороговыми операциями (для HSV & YCrCb). Поскольку эти изображения имеют разные шумы на изображении, выходной сигнал умножения будет иметь еще меньше шума (я видел выходной сигнал на разных экранах, перекрывающиеся области очень малы), следовательно, это может обнаружить цвет кожи почти всегда, и шум будет быть минимальным и, таким образом, поможет в отслеживании кожи лучше.
Приведенный ниже код не является полным, потому что он никогда не выполняется до конца. После этого проводятся морфологические и дилатационные операции, вот и все.
Я впервые задаю вопрос о переполнении стека, и я все еще изучаю Open CV. Извините, если я был чрезмерно описательным, и все предложения приветствуются. Благодарю вас.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <iostream>
#include <opencv2\imgproc\imgproc.hpp>
using namespace cv;
using namespace std;
char key;
Mat image,hsv,ycr;
vector<Mat> channels,ycrs,threshold_output;
int main()
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
{
cout << "Cannot open the web cam" << endl;
return -1;
}
while(1)
{
cap>>image;
cvtColor( image, ycr, CV_BGR2YCrCb ); //Converts into YCRCB
cvtColor( image, hsv, CV_BGR2HSV ); //Converts into HSV
Mat imgThresholded;
Mat imgThresholded1;
inRange(ycr, Scalar(0, 140,105 ), Scalar(255, 165,135), imgThresholded1); //for yrcrcb range
inRange(hsv, Scalar(0, 48,150 ), Scalar(20, 150,255), imgThresholded); //for hsv range
split(imgThresholded1, channels);
split(imgThresholded, ycrs);
for( int i = 0; i <3 ; i++ )
{
multiply(channels[i],ycrs[i], threshold_output[i], 1,-1 );
}//code breaks here
Даже если вход inRange
многоканальные, выход inRange
будет одноканальным CV_8UC1
,
Причина в том, что inRange
вычисляет декартово пересечение:
lower[0] <= img(x, y)[0] <= upper[0]
, А ТАКЖЕlower[1] <= img(x, y)[1] <= upper[1]
, А ТАКЖЕ Другими словами, после того, как он проверил значения пикселей каждого канала по нижней и верхней границе, логический результат «сварили» Логическая-И работа по каналам изображения.
«Разогнанный» — это мой разговорный способ уменьшение или сгиб, где функция может принимать произвольное количество аргументов и ее можно «уменьшить» до одного значения. Суммирование, умножение, конкатенация строк и т. Д.
Поэтому нет необходимости использовать cv::split
на выходе cv::inRange
, На самом деле, потому что выход имеет только один канал, вызывая channels[1]
или же ycrs[1]
будет неопределенным поведением, которое приведет к исключению для отладочной сборки и неопределенному поведению или к аварийному завершению или повреждению памяти для сборки выпуска.