opencv 질문드립니다.

conan1447의 이미지

#include <opencv2/highgui.hpp>
#include <iostream>
 
using namespace cv;
using namespace std;
 
int main() {
 
	const int nAddedValue = 100;
 
	Mat image[20];
 
	image[0] = imread("zero_00.png", IMREAD_GRAYSCALE); // Read the file
	image[1] = imread("zero_01.png", IMREAD_GRAYSCALE); // Read the file
	image[2] = imread("zero_02.png", IMREAD_GRAYSCALE); // Read the file
	image[3] = imread("zero_03.png", IMREAD_GRAYSCALE); // Read the file
	image[4] = imread("zero_04.png", IMREAD_GRAYSCALE); // Read the file
	image[5] = imread("zero_05.png", IMREAD_GRAYSCALE); // Read the file
	image[6] = imread("zero_06.png", IMREAD_GRAYSCALE); // Read the file
	image[7] = imread("zero_07.png", IMREAD_GRAYSCALE); // Read the file
	image[8] = imread("zero_08.png", IMREAD_GRAYSCALE); // Read the file
	image[9] = imread("zero_09.png", IMREAD_GRAYSCALE); // Read the file
	image[10] = imread("zero_10.png", IMREAD_GRAYSCALE); // Read the file
	image[11] = imread("zero_11.png", IMREAD_GRAYSCALE); // Read the file
	image[12] = imread("zero_12.png", IMREAD_GRAYSCALE); // Read the file
	image[13] = imread("zero_13.png", IMREAD_GRAYSCALE); // Read the file
	image[14] = imread("zero_14.png", IMREAD_GRAYSCALE); // Read the file
	image[15] = imread("zero_15.png", IMREAD_GRAYSCALE); // Read the file
	image[16] = imread("zero_16.png", IMREAD_GRAYSCALE); // Read the file
	image[17] = imread("zero_17.png", IMREAD_GRAYSCALE); // Read the file
	image[18] = imread("zero_18.png", IMREAD_GRAYSCALE); // Read the file
	image[19] = imread("zero_19.png", IMREAD_GRAYSCALE); // Read the file
 
	for (int i = 0; i < 20; i++) {
		if (image[i].empty()) // Check for invalid input
			{
				cout << "Could not open or find the image" << std::endl;
				return -1;
			}
	}
 
	Mat dst;
 
	for (int i = 0; i < 20; i++) {
		dst += image[i];
	}
 
	Mat result = dst/20;
 
 
	CV_Assert(result.depth() == CV_8U);
	int nChannels = result.channels();
	int nRows = result.rows;
	int nCols = result.cols * nChannels;
 
	if (result.isContinuous())
	{
		nCols *= nRows;
		nRows = 1;
	}
 
	int i, j;
	uchar* p;
	for (i = 0; i < nRows; ++i)
	{
		p = result.ptr<uchar>(i);
		for (j = 0; j < nCols; ++j)
		{
			int value = p[j] + nAddedValue;
			if (value > 255)
				value = 255;
			p[j] = uchar(value);
		}
	}
 
	namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display
	imshow("Display window", result); // Show our image inside it.
	waitKey(0); // Wait for a keystroke in the window
 
	return 0;
}

랜덤 노이즈가 추가된 20장의 이미지에서 노이즈를 제거하여
1장의 이미지로 출력하는 코드를 만드는 중인데

입력될 20장의 이미지를 산술연산을 하여 노이즈가 거의 없는 1장의 이미지를 만들어내야 하는데,
20장의 이미지들을 덧셈해야 하는데

실행시켜보니 다음과 같은 오류가 나네요.

OpenCV(4.3.0) Error: Sizes of input arguments do not match (The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array') in cv::arithm_op,

입력 인자의 크기가 서로 일치하지 않아서 덧셈 연산이 오류가 발생한다고 번역되는데,
확인해본 결과 20장의 이미지의 크기는 모두 동일합니다.
그럼에도 불구하고 이런 오류가 발생하는 이유를 모르겠네요;;

참고로 덧셈 연산이나 그외 산술 연산을 할 때, opencv에서 제공하는 add, addWeighted 등의 함수는 사용하지 말라고 주의를 받아서

+, -, *, / 등의 연산자나 사용 가능합니다.

위의 코드에서 어느 부분을 어떻게 수정해야 오류가 발생하지 않을까요?

세벌의 이미지

std::string imgpng;
std::string n;
 
for (int i = 0; i < 20; i++) {
	sprintf(n, "%2d", i);
	imgpng="zero" + n +".png";
	image[i] = imread(imgpng, IMREAD_GRAYSCALE); // Read the file
}
이런 식으로 하면 소스 길이를 좀 줄일 거 같고요...
Sizes of input arguments do not match
구글에서 찾아서 나오는 내용들을 보시면 도움이 될 거 같네요.
swish95의 이미지

Mat dst = image[0]
 
for (int i = 1; i < 20; i++) {
   dst += image[i];
}

이런식으로 하면 되지 않을까요?

------------------------------------------------------------
ProgrammingHolic

conan1447의 이미지

원하는 결과가 안나오네요.
실행했을 때 20개의 이미지를 더해서 노이즈가 거의 없는 이미지(이미지 안의 사람이 나와야 함)가 출력되어야 하는데
전체가 흰색인 이미지만 출력되네요.
20개의 이미지를 더한 것을 20으로 나누어서 실행했더니 회색 이미지가 출력됩니다.

이건 어떻게 해야 하나요?

댓글 첨부 파일: 
첨부파일 크기
Image icon 흰색.png13.42 KB
swish95의 이미지

이미지를 합칠때마다 스텝별로 이미지 변화를 관찰해야 되죠
단순히 생각해서 값을 더하기만 하면 결국 최대값인 흰색이 되는거겠네요
그리고 더할때 그 자료형이 256 * 20 의 값을 받을수 있느냐도 문제겠구요

정확히 이미지가 어떤식으로 되어 있는지는 모르지만
비트 연산이나 아니면 노이즈가 들어간 쪽 이미지 컬러값이 커지는지 작아지는지에 따라 해당 값을 버리는 쪽으로 생각해 보심이 좋겠네요

------------------------------------------------------------
ProgrammingHolic