c++ - opencv: single pixal assignment confusion -
i working opencv , c++ project , found weird thing: when try access single pixal value in iplimage , assign other value, run result can operate part of whole image.
relevant code:
iplimage* output_frame = cvcreateimage(size, ipl_depth_8u, 1); iplimage* current_frame = cvcreateimage(size, ipl_depth_8u, 1); while((current_frame = cvqueryframe(video_gray)) != 0 ) { (int row=0;row<height;row++) { uchar* ptr_current_frame = (uchar *)(current_frame->imagedata+current_frame->widthstep*row); uchar* ptr_output_frame = (uchar *)(output_frame->imagedata+output_frame->widthstep*row); (int cols=0;cols<width;cols++) { //other codes... ptr_output_frame[cols]=ptr_current_frame[cols]; } } }
the result left part of image copied output_frame. , when run following code:
iplimage* output_frame = cvcreateimage(size, ipl_depth_8u, 1); iplimage* current_frame = cvcreateimage(size, ipl_depth_8u, 1); while((current_frame = cvqueryframe(video_gray)) != 0 ) { (int row=0;row<height;row++) { uchar* ptr_current_frame = (uchar *)current_frame->imagedata+current_frame->width*row; uchar* ptr_output_frame = (uchar *)output_frame->imagedata+output_frame->width*row; (int cols=0;cols<width;cols++) { //other codes... ptr_output_frame[cols]=ptr_current_frame[cols]; } } }
i got upside part of image in output_frame.
i cannot the whole image copy in output_frame either way. me this? lot!
[updates] 05/16/2015
i have found out output_frame->widthstep different current->widthstep after current_frame executed in following code:
current_frame = cvqueryframe(video_gray);
it makes sense why first part of code wouldnt work. still dont know why second part of code doesnt work. have whole codes updated here , hope can me make right. appreciate help.
cvcapture* video_gray = cvcreatefilecapture("test_gray.avi"); const double fps = cvgetcaptureproperty(video_gray, cv_cap_prop_fps); const int width = (int)cvgetcaptureproperty(video_gray, cv_cap_prop_frame_width); const int height = (int)cvgetcaptureproperty(video_gray, cv_cap_prop_frame_height); const cvsize size = cvsize(width, height); iplimage* current_frame = cvcreateimage(size, ipl_depth_8u, 1); iplimage* output_frame=cvcreateimage(size, ipl_depth_8u, 1); int flag = 0; cvnamedwindow("test",1); cvnamedwindow("test2",1); while((current_frame = cvqueryframe(video_gray)) != 0 ) { cout<<flag++<<endl; if(flag<500) continue; (int row=0;row<height;row++) { uchar* ptr_current_frame = (uchar *)(current_frame->imagedata+current_frame->widthstep*row); uchar* ptr_output_frame = (uchar *)(output_frame->imagedata+output_frame->widthstep*row); (int cols=0;cols<width;cols++) { ptr_output_frame[cols]= ptr_current_frame[cols]; } } cvshowimage("test",output_frame); cvshowimage("test2",current_frame); cvwaitkey(10); }
you don't handle number of channels...
please try
iplimage* output_frame = cvcreateimage(size, ipl_depth_8u, 1); iplimage* current_frame = cvcreateimage(size, ipl_depth_8u, 1); while((current_frame = cvqueryframe(video_gray)) != 0 ) { (int row=0;row<height;row++) { uchar* ptr_current_frame = (uchar *)(current_frame->imagedata+current_frame->widthstep*row); uchar* ptr_output_frame = (uchar *)(output_frame->imagedata+output_frame->widthstep*row); (int cols=0;cols<width;cols++) { //other codes... // here insead take care of channels too. write ne channel output ptr_output_frame[cols]=ptr_current_frame[cols*current_frame->nchannels]; } } }
but should try switch c++ api: try this:
cv::videocapture video = cv::videocapture("test_gray.avi"); int width = ... int height = ... cv::mat image_captured; cv::mat image_gray; // if wanted cv::mat image_output1 = cv::mat(height, width, cv_8uc1); cv::mat image_output2 = cv::mat(height, width, cv_8uc1); while(video.read(image_captured)) { // if want convert image if(image_captured.channels() > 1) { cv::cvtcolor(image_captured, image_gray, cv_bgr2gray); } else { image_gray = image_captured; } [...] for(int j=0; j<height; ++j) { for(int i=0; i<width; ++i) { image_output1.at<uchar>(j,i) = image_gray.at<uchar>(j,i); // read single channel image image_output1.at<uchar>(j,i) = image_captured.at<cv::vec3b>(j,i)[0]; // read first channel of multi-channel image } } } cv::imshow("output1", image_output1); cv::imshow("output2", image_output2); cv::imshow("input", image_capured); cv::waitkey(0); }
much easier use, , can still make more efficient using row-pointers in each iteration etc
Comments
Post a Comment