RECOSTRUCTION IMAGE WITH OPENCV
Hello to all!!! I'm doing a little project for rebuild une image. I must load image from my path then. I used a grid 40x40 pixels for divide image in some little images. I must then rebuild image in order adding a red background. I think that this project is a bit useless but this is for another project. For my project is very important the division of the image and its orderly reconstruction. I post below my solution:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <opencv2\opencv.hpp>
#include "opencv\highgui.h"
#include "opencv\cv.h"
using namespace cv;
using namespace std;
Mat add_piece_of_frame(Mat, Mat, int, int);
Mat add_piece_of_frame_red(Mat, Mat, int, int);
int main(int argc, char** argv)
{
Mat bkg_read = imread("C:\\Users\\Fabrizio\\Desktop\\frame\\VIDEO_PER_TESI\\Scene1.jpg",CV_LOAD_IMAGE_COLOR);
IplImage * bkg = cvCloneImage( &(IplImage)bkg_read );
namedWindow("original", 1);
cvShowImage("original", bkg);
cvWaitKey(3333);
//Mat background(bkg_read);
Mat ricostruzione[48];
int aa[48];
int bb[48];
int m = 0;
for(int a=0; a<320; a+=40)
{
for(int b=0; b<240; b+=40)
{
Mat SUPPORT (bkg_read, Rect(a,b,40,40));
ricostruzione[m] = SUPPORT.clone();
aa[m] = a;
bb[m] = b;
cout<<"coordinate: "<<endl;
cout<<"a: "<<aa[m];
cout<<" b: "<<bb[m]<<endl;
m++;
}
}
int A=0;
while(A<1)
{
Mat output = cv::Mat::zeros(240, 320, CV_32FC3);
Mat output_red = cv::Mat::zeros(240, 320, CV_32FC3);
for ( int t=0; t<48; t++)
{
output_red = add_piece_of_frame_red(ricostruzione[t] , output_red, aa[t] , bb[t]);
}
IplImage * exit_red = cvCloneImage( &(IplImage)output_red );
namedWindow("output_red", 1);
cvShowImage("output_red",exit_red);
cvWaitKey(3333);
for ( int u=0; u<48; u++)
{
output = add_piece_of_frame(ricostruzione[u] , output, aa[u] , bb[u]);
}
IplImage * exit = cvCloneImage( &(IplImage)output );
namedWindow("output", 1);
cvShowImage("output",exit);
cvWaitKey(3333);
}
}
Mat add_piece_of_frame(Mat A , Mat B, int r, int c)
{
Rect Roi(r, c, 40, 40);
B(Roi) = B(Roi) + A.clone();
return B;
}
Mat add_piece_of_frame_red(Mat A, Mat B, int r, int c)
{
Scalar color = Scalar(0, 0, 255);
Mat mask = Mat(40, 40, CV_32FC3, color);
Mat result;
addWeighted(A, 0.5, mask, 0.5, 0, result, CV_32FC3);
Rect Roi(r, c, 40, 40);
B(Roi) = B(Roi) + result.clone();
return B;
}
Why using IplImage instead of Mat? Just for displaying? There are function that accepts cv::Mat inputs: cv::imshow(...) and cv::waitKey() for waiting for the key until going to next step
You can also use
const cv::Mat& param
for gaining speed. And create a new Map inside he function for returning it. Or usecv::Map& B
If you want to change BFirst of all, don't use the deprecated C-api (IplImage and cvWhatever functions). And then, what is your exact problem?
I think that my problem is the recostruction. when I use the function "add_piece_of_frame" it shows a all white image nd when I use other function it don't work and don't show anything. I suppose that image have 3 channel and when I divide it in "ricostruzione[m]" I don't have 3 channels.
when the program execute : " B(Roi) = B(Roi)+A.clone();" obtain this message:
Unhandled exception at 0x7427d8a8 in OPENCV_PROVA.exe: Microsoft C++ exception: cv::Exception at memory location 0x0017c6b8.. and in a prompt I have: opencv error: bad argument( when the input arrays in add/substract/multiply/divide functions have different types, the output array type must be explicitly specified) in cv::arithm_op, file ........\opencv\modules\core\src\arithm.cpp, line 1313 how to fix this? and the red?
I think your problem is that you modify
B
when doing thatB(Roi) = ...
And when you are doing this a few times, then you get in that saturation case so you are getting all 255...excuse me but with opencv I'm just the starting and I don't understand the problem. I divide one big matrix and I save orderly each single piece of matrix wich size is 40x40. After I take these pieces and I put them in a big matrix for output. I don't understand the problem of memory locations...
I think that one problem is the read of matrix over the matrix size ( rows or columns)...but I think also that if the division is correct then the reconstruction must work....help meeeee
@baro just do
B(Roi) = result.clone();
andB(Roi) = A.clone();
. That will assign the proper pieces. Adding the matrices is equal to adding the pixel intensities, and after a while you will end up with 255 pixel values, i.e. white piecesexcuse me but B is a zeros matrix....and I modify a piece of matrix only one time. In for cycle the Roi area change oech times. Or not?
Yes, true, my fault. I hadn't read the code thoroughly... The error that you posted is due to such manual addings, because your read image is
CV_8UC3
(I guess) and yourB
matrix isCV_32FC3
. OpenCV does not know what type to output is you don't tell. However, as I said, don't use such sum, it makes no sense at all. About not having 3-channel images when inputting them into vectorricostruzione
, I'd suggest using instead ofMat ricostruzione[48];
the following:vector<Mat> ricostruzione; ricostruzione.reserve(48);