Related
Photo is here:
I want to see this white man in green when I clicked left-mouse and [CTRL] button.
The code looks 8-neighbour point of the clicked point and makes recursive.
The code works correctly in the small matrix. But in this photo, I get a memory error. I want to see the man in green. How can I fix the code correctly?
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
int n=0;
void yap(int i,int j,Mat* res){
ostringstream t;
Mat *rgb=(Mat*) res;
Mat res1;
res1=*rgb;
t<<"fark_binary"<<n<<".jpg";
imwrite(t.str(),res1);
if(res1.at<Vec3b>(i,j)[0]>=200){
cout<<j<<"\n"<<i;
res1.at<Vec3b>(i,j)[0]=0;
res1.at<Vec3b>(i,j)[1]=255;
res1.at<Vec3b>(i,j)[2]=0;
cout<<"yapıldı";
}
if(res1.at<Vec3b>(i-1,j-1)[0]>=200){
yap(i-1,j-1,&res1);
res1.at<Vec3b>(i-1,j-1)[0]=0;
res1.at<Vec3b>(i-3,j-3)[1]=255;
res1.at<Vec3b>(i-3,j-3)[2]=0;
}
if(res1.at<Vec3b>(i-1,j)[0]>=200){
yap(i-1,j,&res1);
res1.at<Vec3b>(i-1,j)[0]=0;
res1.at<Vec3b>(i-1,j)[1]=255;
res1.at<Vec3b>(i-1,j)[2]=0;
}
if(res1.at<Vec3b>(i-1,j+1)[0]>=200){
res1.at<Vec3b>(i-1,j+1)[0]=0;
res1.at<Vec3b>(i-1,j+1)[1]=255;
res1.at<Vec3b>(i-1,j+1)[2]=0;
}
if(res1.at<Vec3b>(i,j-1)[0]>=200){
yap(i,j-1,&res1);
res1.at<Vec3b>(i,j-1)[0]=0;
res1.at<Vec3b>(i,j-1)[1]=255;
res1.at<Vec3b>(i,j-1)[2]=0;
}
if(res1.at<Vec3b>(i,j+1)[0]>=200){
yap(i,j+1,&res1);
res1.at<Vec3b>(i,j+1)[0]=0;
res1.at<Vec3b>(i,j+1)[1]=255;
res1.at<Vec3b>(i,j+1)[2]=0;
}
if(res1.at<Vec3b>(i+1,j-1)[0]>=200){
yap(i+1,j-1,&res1);
res1.at<Vec3b>(i+1,j-1)[0]=0;
res1.at<Vec3b>(i+1,j-1)[1]=255;
res1.at<Vec3b>(i+1,j-1)[2]=0;
}
if(res1.at<Vec3b>(i+1,j)[0]>=200){
yap(i+1,j,&res1);
res1.at<Vec3b>(i+1,j)[0]=0;
res1.at<Vec3b>(i+1,j)[1]=255;
res1.at<Vec3b>(i+1,j)[2]=0;
}
if(res1.at<Vec3b>(i+1,j+1)[0]>=200){
yap(i+1,j+1,&res1);
res1.at<Vec3b>(i+1,j+1)[0]=0;
res1.at<Vec3b>(i+1,j+1)[1]=255;
res1.at<Vec3b>(i+1,j+1)[2]=0;
}
}
void mouseTikla(int evt, int x, int y, int flags, void* param)
{ Vec3b color;
Mat* rgb = (Mat*) param;
Mat p;
p=*rgb;
if (flags == (CV_EVENT_LBUTTONDOWN+CV_EVENT_FLAG_CTRLKEY))
{
yap(y,x,&p);
cout<<x<<y;
}
}
int main(){
Mat res;
res=imread("C:/Users/giray/Desktop/27.jpg");
int i;
int j;
//res1.data[res.channels()*(res.cols*(i)+(j))];
namedWindow("Secim", 1);
setMouseCallback("Secim", mouseTikla, &res);
imshow("Secim", res);
waitKey(0);
return 0;
}
This code is so wrong in a thousand ways...
Never use recursion if you can do it without it
Why did you actually create so many pointers to that single image?
Formatting helps, really.
Memory reallocation is just insane here.
Here's the better version of your code:
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <queue>
using namespace cv;
using namespace std;
void yap(int i,int j, Mat* res){
queue<pair<int, int>> q;
q.push(pair<int, int>(i, j));
while (!q.empty())
{
pair<int, int> p = q.front();
q.pop();
if ((p.first < 0) ||
(p.second < 0) ||
(p.first >= res->rows) ||
(p.second >= res->cols))
continue;
if (res->at<Vec3b>(p.first, p.second)[0] > 200)
{
res->at<Vec3b>(p.first, p.second) = {0, 255, 0};
q.push(pair<int,int>(p.first - 1, p.second - 1));
q.push(pair<int,int>(p.first + 1, p.second + 1));
q.push(pair<int,int>(p.first - 1, p.second + 1));
q.push(pair<int,int>(p.first + 1, p.second - 1));
q.push(pair<int,int>(p.first + 1, p.second));
q.push(pair<int,int>(p.first - 1, p.second));
q.push(pair<int,int>(p.first, p.second + 1));
q.push(pair<int,int>(p.first, p.second - 1));
}
}
}
void mouseTikla(int evt, int x, int y, int flags, void* param)
{
Mat* rgb = (Mat*) param;
if (evt == CV_EVENT_LBUTTONDOWN)
{
yap(y,x,rgb);
imshow("Secim", *rgb);
}
}
int main(){
Mat res;
res=imread("put_your_path_here");
namedWindow("Secim", 1);
setMouseCallback("Secim", mouseTikla, &res);
imshow("Secim", res);
waitKey(0);
return 0;
}
I recently start to learn opencl and how to create kernel for OpenCV as well.
I am still working with the basics.
I need to implement an opencl kernel for calculate the covariance matrix.
This function don't have any opencl kernel already implemented by opencv's fundation.
Technically what I want to process is that :
cv::RNG tutu(std::time(nullptr)); // This is only for check the improvement of the method over the executions
int sz = tutu.uniform(1,20);
cv::Mat_<float> a1(1,sz);
cv::Mat_<float> a2(a1.size());
cv::Mat_<float> c2;
for(std::size_t i=0;i<sz;i++)
{
a1(i) = tutu.uniform(0,300);
a2(i) = tutu.uniform(300,600);
}
cv::Mat_<float> f;
cv::vconcat(a1,a2,f);
// process the Covariance Matrix :
cv::gemm(one,f,-0.5f,f,1.f,c2,0);
cv::gemm(c2.t(),c2,1.f,cv::noArray(),0.f,c2);
I found OpenCV's fundation have implemented an OpenCL kernel for both gemm and the function transpose.
So I tried to derivate an implementation from an exemple directly from OpenCV's source.
I wrote this :
ocl.h :
void CovarMatrix( cv::Mat_<float>& src,cv::Mat_<float>& covar);
ocl.cpp :
#include <memory>
#include <fstream>
#include <sstream>
#include <iterator>
#include <opencv2/core.hpp>
#include <opencv2/core/ocl.hpp>
namespace test
{
namespace ocl
{
namespace
{
std::unique_ptr<cv::ocl::ProgramSource> cov_src;
void init_cov()
{
std::ifstream stream("../mahalanobis/covarianceMatrix.cl");
std::ostringstream sstream;
sstream << stream.rdbuf();
cv::String norm_file_content = sstream.str();
stream.close();
cov_src.reset(new cv::ocl::ProgramSource(norm_file_content));
}
}
static bool ocl_gemm( cv::Mat_<float>& matA, cv::Mat_<float>& matB, cv::Mat_<float>& CV_OUT matD)
{
cv::Mat_<float> tmp;
cv::Mat_<float> tmp2;
cv::Size sizeA = matA.size(), sizeB = matB.size();
cv::Size sizeD(sizeB.width, sizeA.height);
const cv::ocl::Device & dev = cv::ocl::Device::getDefault();
int max_wg_size = (int)dev.maxWorkGroupSize();
int block_size = (max_wg_size / 32 < 32) ? (max_wg_size / 16 < 16) ? (max_wg_size / 8 < 8) ? 1 : 8 : 16 : 32;
// matD.create(sizeD);
// tmp2.create(matD.t().size());
tmp.create(sizeD);
tmp2.create(tmp.t().size());
matD.create(sizeD.width,sizeD.width);
cv::UMat A = matA.getUMat(cv::ACCESS_READ,cv::USAGE_ALLOCATE_DEVICE_MEMORY);
cv::UMat B = matB.getUMat(cv::ACCESS_READ,cv::USAGE_ALLOCATE_DEVICE_MEMORY);
// cv::UMat D = matD.getUMat(cv::ACCESS_WRITE,cv::USAGE_ALLOCATE_DEVICE_MEMORY);
cv::UMat D = tmp.getUMat(cv::ACCESS_WRITE,cv::USAGE_ALLOCATE_DEVICE_MEMORY);
// cv::UMat E(sizeD.width,sizeD.height,CV_32FC1,cv::Scalar::all(0.),cv::USAGE_ALLOCATE_DEVICE_MEMORY);
cv::UMat E = tmp2.getUMat(cv::ACCESS_WRITE,cv::USAGE_ALLOCATE_DEVICE_MEMORY);
cv::UMat F = matD.getUMat(cv::ACCESS_WRITE,cv::USAGE_ALLOCATE_DEVICE_MEMORY);
matB.copyTo(D);
int vectorWidths[] = { 4, 4, 2, 2, 1, 4, 1, -1 };
int kercn = cv::ocl::checkOptimalVectorWidth(vectorWidths, B, D);
cv::String opts = cv::format(
"-I /home/administrateur/lib_dir/opencv_dir/opencv_304/opencv/modules/core/src/opencl/ -D T=float -D T1=float -D WT=%s -D cn=1 -D kercn=%d -D LOCAL_SIZE=%d %s -D HAVE_C -D TILE_DIM=32 -D BLOCK_ROWS=8 -D rowsPerWI=1 ",
cv::ocl::typeToStr(CV_32FC(kercn)),
kercn, block_size,
(sizeA.width % block_size !=0) ? "-D NO_MULT" : "");
cv::ocl::Kernel k("covarianceMatrix", *cov_src, opts);
k.args(cv::ocl::KernelArg::ReadOnlyNoSize(A),
cv::ocl::KernelArg::ReadOnlyNoSize(B, 1, kercn),
cv::ocl::KernelArg::ReadWrite(D, 1, kercn),
sizeA.width,
cv::ocl::KernelArg::ReadWrite(E,kercn,1),
cv::ocl::KernelArg::ReadWrite(F,kercn,kercn)
);
std::size_t globalsize[2] = { static_cast<std::size_t>(sizeD.width / kercn), static_cast<std::size_t>(sizeD.height)};
std::size_t localsize[2] = { static_cast<std::size_t>(block_size), static_cast<std::size_t>(block_size)};
return k.run(2, globalsize, block_size!=1 ? localsize : nullptr, false);
}
void CovarMatrix( cv::Mat_<float>& src,cv::Mat_<float>& covar)
{
if(!covar.empty())
covar.release();
cv::Mat_<float> o = cv::Mat_<float>::ones(src.rows,src.rows);
if(!cov_src)
init_cov();
ocl_gemm(o,src,covar);
}
covarianceMatrix.cl :
#include "gemm.cl"
#include "transpose.cl"
__kernel void covarianceMatrix
(
__global const uchar * A_ptr, int A_step, int A_offset,
__global const uchar * B_ptr, int B_step, int B_offset,
__global uchar * D_ptr, int D_step, int D_offset, int D_rows, int D_cols,
int n,
__global uchar * E_ptr, int E_step, int E_offset, int E_rows, int E_cols,
__global uchar * F_ptr, int F_step, int F_offset, int F_rows, int F_cols
)
{
// cv::gemm(src2,src1,-0.5,src1,1.f,src2);
// cv::gemm(src2.t(),src2,1.f,cv::noArray(),0.f,dest);
gemm(A_ptr,A_step,A_offset,
B_ptr,B_step,B_offset,
D_ptr,D_step,D_offset,D_rows,D_cols,
n,-0.5f,1.f);
transpose(D_ptr,D_step,D_offset,D_rows,D_cols*sizeof(float),
E_ptr,E_step,E_offset);
gemm(E_ptr,E_step,E_offset,
D_ptr,D_step,D_offset,
F_ptr,F_step,F_offset,F_rows,F_cols,
n,1.f,0.f);
}
If the size of the matrix is fewer than 6 is work perfectly :).
Otherwise ... not really.
It can be check with this code :
cv::RNG tutu(std::time(nullptr));
int sz = tutu.uniform(1,20);
cv::Mat_<float> a1(1,sz);
cv::Mat_<float> a2(a1.size());
for(std::size_t i=0;i<sz;i++)
{
a1(i) = tutu.uniform(0,300);
a2(i) = tutu.uniform(300,600);
}
cv::Mat_<float> f;
cv::vconcat(a1,a2,f);
cv::Mat_<float> c1;
cv::Mat_<float> c2;
cv::Mat_<float> mean;
// reference
cv::calcCovarMatrix(f,c1,mean,cv::COVAR_ROWS | cv::COVAR_NORMAL,CV_32F);
// check
test::ocl::CovarMatrix(f,c2);
std::size_t cnt(0.f);
for(auto it = c1.begin(),it2 = c2.begin();it != c1.end();it++,it2++)
if(*it == *it2)
cnt++;
std::cout<<"check "<<cnt<<" "<<c1.total()<<std::endl;
I am still new in OpenCL and I am interrested to know what I did wrong.
Does someone already implemented an OpenCL kernel for process the covariance matrix with OpenCV ?
Thank in advance for any help.
I resign myself to write this code :
void ocl_CovarMatrix(cv::Mat_<float>& src,cv::Mat_<float>& covar)
{
cv::UMat usrc = src.getUMat(cv::ACCESS_READ,cv::USAGE_ALLOCATE_DEVICE_MEMORY);
cv::UMat ones = cv::UMat::ones(usrc.rows,usrc.rows,usrc.type());
cv::UMat utmp;
double beta = 1.;
double alpha = -1. / static_cast<double>(usrc.rows);
cv::gemm(ones,usrc,alpha,usrc,beta,utmp);
cv::gemm(utmp.t(),utmp,beta,cv::noArray(),0.,utmp);
utmp.copyTo(covar);
ones.release();
utmp.release();
usrc.release();
}
I suspect the GPU memory is updated everytime a function is call, that make that code slower rather than if it has been written in one Kernel.
But it work efficiently.
I am still interested by another solution if maybe someone have an idea.
I am using opencv c++ on Mac OS X 10.10.2 to process video frames and display them. The performance of imshow with waitKey to display the video is extremely slow.
I have the following code which displays HD (1920x1080) grayscale frames correctly, except that it runs about 10 times too slow (i.e. 2 to 3 frames per second instead of 30 frames per second).
cv::Mat framebuf[TEST_COUNT];
//--- Code here to allocate and fill the frame buffer with about 4 seconds of video. This part works correctly.
//--- This loop runs too slow by factor of approximately 10x
for (int f = 0; f < TEST_COUNT; f++)
{
cv::imshow(windowName, framebuf[f]);
cv::waitKey(33);
}
Can anyone suggest how to get real-time or near real-time performance from opencv imshow()? I have seen many posts that state that they are displaying video in real-time or even faster than real-time, so I am not sure what I am doing wrong. Any help would be greatly appreciated.
I could be wrong but for me the problem is not with your code, but with your os/configuration. I've written a small test:
import cv2
import numpy as np
from random import randrange
img = np.zeros((1920, 1080), dtype = np.uint8)
counter = 0
while counter < 1000:
cv2.line(img, (randrange(0, 1920), randrange(0, 1080)), (randrange(0, 1920), randrange(0, 1080)), (randrange(0, 255)))
cv2.imshow('test', img)
temp = cv2.waitKey(1)
counter += 1
print counter
On my machine (Core 2 duo 2,6Ghz x64, 8gb ram, ssd) it took about 30 seconds for this test to complete. Run it and if you will get significantly bigger time than definitelly something is wrong with your laptop/opencv configuration/etc. I've used OpenCV 2.4.x on Mac OS X (it was 10.9 i think) and it was running fine. Reinstalling OpenCV is the most obvious solution which comes to my mind. When you remove OpenCV, use brew to install it again - brew install opencv --with-tbb --with-python --with-ffpmeg (or something similar - check using brew options opencv) should be fine. First options tells brew to build opencv with tbb(thread building block - library for multithreading, sometimes can significantly improve speed), second to install python wrappers, and the last one to install ffmpeg(handle codecs etc).
You would have to reduce the input to the function wait key. Try using a lower number in the range of 2-5. It also depends on the other processes you have running simultaneously, try shutting down other processes and see if it improves
you can create your own window to show the image. Add MyWindow.m MyWindow.h file to project.
MyWindow.h
#ifndef MY_WINDOW_H
#define MY_WINDOW_H
#ifdef __cplusplus
extern "C" {
#endif
void* createNSWindow(int x, int y, int w, int h);
void renderNSWindow(void* inwindow, void* data, int w, int h, int c);
void processNSEvent();
#ifdef __cplusplus
}
#endif
#endif
usage, in main.cpp, do not forget waitKey
#include "MyWindow.h"
// need create a cv window and do nothing
cv::namedWindow("xxx", 1);
// create window
void* w = createNSWindow(0, 0, 0, 0);
// frame image
cv::Mat frameImage;
// render loop
renderNSWindow(w, frameImage.data, frameImage.cols, frameImage.rows, frameImage.channels());
// need waitKey to display window
processNSEvent();
implement, in MyWindow.m, delete import "MyWindow.h"
#import <Cocoa/Cocoa.h>
#interface MyWindow : NSWindow
#property(nonatomic, strong) NSImageView *imgv;
#end
#implementation MyWindow
#end
static NSImage* _createNSImage(void* data, int w, int h, int c);
void* createNSWindow(int x, int y, int w, int h) {
NSRect screenFrame = [[NSScreen mainScreen] frame];
NSRect frame = NSMakeRect(x, y, w, h);
if (w == 0 || h == 0) {
frame = screenFrame;
}
MyWindow* window = [[MyWindow alloc] initWithContentRect:frame
styleMask:NSWindowStyleMaskBorderless
backing:NSBackingStoreBuffered
defer:NO] ;
//_initApp(window);
[window makeKeyAndOrderFront:NSApp];
window.titleVisibility = TRUE;
window.styleMask = NSWindowStyleMaskResizable | NSWindowStyleMaskTitled |NSWindowStyleMaskFullSizeContentView;
window.imgv = [[NSImageView alloc] initWithFrame:NSMakeRect(0, 0, frame.size.width, frame.size.height)];
[window.contentView addSubview:window.imgv];
return (void*)CFBridgingRetain(window);
}
static NSImage* _createNSImage(void* data, int w, int h, int c) {
size_t bufferLength = w * h * c;
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data, bufferLength, NULL);
size_t bitsPerComponent = 8;
size_t bitsPerPixel = c * bitsPerComponent;
size_t bytesPerRow = c * w;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast;
if (c < 4) {
bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNone;
unsigned char* buf = data;
for(int i = 0; i < w*h; i++) {
unsigned char temp = buf[i*c];
buf[i*c] = buf[i*c+c-1];
buf[i*c+c-1] = temp;
}
}
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef iref = CGImageCreate(w,
h,
bitsPerComponent,
bitsPerPixel,
bytesPerRow,
colorSpaceRef,
bitmapInfo,
provider, // data provider
NULL, // decode
YES, // should interpolate
renderingIntent);
NSImage* image = [[NSImage alloc] initWithCGImage:iref size:NSMakeSize(w, h)];
return image;
}
void renderNSWindow(void* inwindow, void* data, int w, int h, int c) {
MyWindow* window = (__bridge MyWindow*)inwindow;
window.imgv.image = _createNSImage(data, w, h, c);
}
void processNSEvent() {
for (;;)
{
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:[NSDate distantPast]
inMode:NSDefaultRunLoopMode
dequeue:YES];
if (event == nil)
break;
[NSApp sendEvent:event];
}
}
other things, the waitKey now take about 20ms, you can do OpenCV in background thread, and show window in main thread. Also use processNSEvent instead of waitKey that only take about 10ms.
full source code:
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <dispatch/dispatch.h>
#include "MyWindow.h"
using namespace std;
using namespace cv;
int opencvfunc(int argc, const char *argv[]);
bool newFrame = false;
cv::Mat back_frame;
int main(int argc, const char * argv[]) {
cv::namedWindow("render", 1);
void* w = createNSWindow(0, 0, 0, 0);
dispatch_queue_t opencvq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_async(opencvq, ^{
opencvfunc(argc, argv);
});
while(true) {
usleep(3*1000);
if(newFrame) {
std::chrono::system_clock::time_point starttime = std::chrono::system_clock::now();
renderNSWindow(w, back_frame.data, back_frame.cols, back_frame.rows, back_frame.channels());
newFrame = false;
//auto key = cv::waitKey(1);
//if (key == 'q') {
// break;
//}
processNSEvent();
std::chrono::system_clock::time_point endtime = std::chrono::system_clock::now();
std::cout << "imshow:" << std::chrono::duration_cast<std::chrono::duration<double>>(endtime-starttime).count()*1000 << std::endl;
}
}
return 0;
}
int opencvfunc(int argc, const char *argv[]) {
cv::VideoCapture cap;
cap.open(0);
if (!cap.isOpened()) {
std::cout << "Couldn't open camera 0." << endl;
return EXIT_FAILURE;
}
Mat frame, unmodified_frame;
for (;;) {
cap >> frame; // get a new frame from camera
if (frame.empty()) { // stop if we're at the end of the video
break;
}
//unmodified_frame = frame.clone();
// ...
back_frame = frame.clone();
newFrame = true;
}
return EXIT_SUCCESS;
}
OpenCV 4 had resolved this issue, please update to new version.
One more thing, process video and show video in two thread.
#include <stdio.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <dispatch/dispatch.h>
using namespace cv;
using namespace std;
bool newFrame = false;
Mat back_frame;
int opencvmain(int argc, char** argv ) {
// open camear
cv::VideoCapture cap;
cap.open(0);
if (!cap.isOpened()) {
std::cout << "Couldn't open camera 0." << std::endl;
return EXIT_FAILURE;
}
// define frame images
cv::Mat frame;
// frame loop
for (;;) {
// get video frame
cap >> frame;
if (frame.empty()) {
break;
}
// render
back_frame = frame.clone();
newFrame = true;
}
return 0;
}
int main(int argc, char** argv ) {
namedWindow("video", WINDOW_AUTOSIZE );
dispatch_queue_t opencvq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(opencvq, ^{
opencvmain(argc, argv);
});
while(true) {
usleep(3*1000);
if(newFrame) {
imshow("video", back_frame);
auto key = cv::waitKey(1);
if (key == ' ') {
break;
}
newFrame = false;
}
}
return 0;
}
When I run this program and adjust the slider multiple times bar the image appears different even though it is at the same slider position. If you try this code, move the slider from the minimum to maximum position back and forth several times and you can see a slight alteration to the image each time.
I have traced the point at which this happens to the line running the add function in my onProgram6Trackbar1 function. Removing it removes the variations between slide movements. Why is this happening?
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
#include <cmath>
class ProgramData {
public:
ProgramData() {
k1=0;
k2=0;
k3=0;
k4=0;
k5=0;
}
int k1;
int k2;
int k3;
int k4;
int k5;
Mat * source_U8C3;
Mat * temp1_U8C3;
Mat * temp2_U8C3;
Mat * temp3_U8C1;
Mat * temp4_U8C1;
Mat * temp5_U8C1;
Mat * temp6_U8C1;
Mat * temp7_U8C1;
vector<Mat> tempv1_U8C1;
vector<Mat> tempv2_U8C1;
Mat * output_U8C1;
Mat * output_U8C3;
Mat * dim1by1;
};
static void onProgram6Trackbar1(int v, void* vp) {
ProgramData * pd = (ProgramData *) vp;
*(pd->temp3_U8C1) = pd->tempv1_U8C1[2].clone();
inRange(*(pd->temp3_U8C1), pd->k1, 255, *(pd->temp4_U8C1));
bitwise_not(*(pd->temp4_U8C1), *(pd->temp5_U8C1));
bitwise_and(*(pd->temp5_U8C1), *(pd->temp3_U8C1), *(pd->temp6_U8C1));
bitwise_or(pd->temp6_U8C1, Scalar(pd->k1), pd->temp7_U8C1, pd->temp4_U8C1);
imshow( "Glare Reduction 4", *(pd->temp7_U8C1));
}
void program6(char * argv) {
ProgramData pd;
pd.k1 = 0;
Mat source = imread(argv, IMREAD_COLOR); // Read the file
pd.source_U8C3 = &source;
Size s( pd.source_U8C3->size().width / 1.3, pd.source_U8C3->size().height / 1.3 );
resize( *(pd.source_U8C3), *(pd.source_U8C3), s, 0, 0, CV_INTER_AREA );
pd.output_U8C3 = new Mat(pd.source_U8C3->rows,pd.source_U8C3->cols,pd.source_U8C3->type());
pd.output_U8C1 = new Mat(pd.source_U8C3->rows,pd.source_U8C3->cols,CV_8UC1);
//pd.temp1_U8C3 = new Mat(pd.source_U8C3->rows,pd.source_U8C3->cols,pd.source_U8C3->type());
pd.temp2_U8C3 = new Mat(pd.source_U8C3->rows,pd.source_U8C3->cols,pd.source_U8C3->type());
pd.temp3_U8C1 = new Mat(pd.source_U8C3->rows,pd.source_U8C3->cols,CV_8UC1);
pd.temp4_U8C1 = new Mat(pd.source_U8C3->rows,pd.source_U8C3->cols,CV_8UC1);
pd.temp5_U8C1 = new Mat(pd.source_U8C3->rows,pd.source_U8C3->cols,CV_8UC1);
pd.temp6_U8C1 = new Mat(pd.source_U8C3->rows,pd.source_U8C3->cols,CV_8UC1);
pd.temp7_U8C1 = new Mat(pd.source_U8C3->rows,pd.source_U8C3->cols,CV_8UC1);
pd.dim1by1 = new Mat(100,800,CV_8UC1);
cout << "source type = " << pd.source_U8C3->type() << endl;
if(! pd.source_U8C3->data ) { cout << "Could not open image" << std::endl; return;}
cvtColor(*(pd.source_U8C3), *(pd.temp2_U8C3), CV_BGR2HSV); // original to hsv
split(*(pd.temp2_U8C3), pd.tempv1_U8C1);
namedWindow( "Glare Reduction - Controls", WINDOW_AUTOSIZE ); // Create a window for display.
onProgram6Trackbar1(0,&pd);
createTrackbar("k1", "Glare Reduction - Controls", &(pd.k1), 255, &onProgram6Trackbar1, &pd);
imshow( "Glare Reduction - Controls", *(pd.dim1by1) ); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
}
int main( int argc, char** argv )
{
program6("Blocks1.jpg");
}
Update 1:
New code posted below. I tried changing the code to not use any Mat pointers. Still does the exact same thing.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
#include <cmath>
class ProgramData {
public:
ProgramData() {
k1=0;
}
int k1;
Mat source_U8C3;
Mat temp1_U8C3;
Mat temp2_U8C3;
Mat temp3_U8C1;
Mat temp4_U8C1;
Mat temp5_U8C1;
Mat temp6_U8C1;
Mat temp7_U8C1;
vector<Mat> tempv1_U8C1;
vector<Mat> tempv2_U8C1;
Mat output_U8C1;
Mat output_U8C3;
Mat dim1by1;
};
static void onProgram6Trackbar1(int v, void* vp) {
ProgramData * pd = (ProgramData *) vp;
pd->temp3_U8C1 = pd->tempv1_U8C1[2].clone();
inRange(pd->temp3_U8C1, Scalar(pd->k1), Scalar(255), pd->temp4_U8C1);
bitwise_not(pd->temp4_U8C1, pd->temp5_U8C1); // Note for monday, here does not work below works. Why?
bitwise_and(pd->temp5_U8C1, pd->temp3_U8C1, pd->temp6_U8C1);
bitwise_or(pd->temp6_U8C1, Scalar(pd->k1), pd->temp7_U8C1, pd->temp4_U8C1);
imshow( "Glare Reduction 4", pd->temp7_U8C1);
}
int main( int argc, char** argv ) {
ProgramData pd;
pd.k1 = 0;
pd.source_U8C3 = imread("Photo Examples/Blocks1.jpg", IMREAD_COLOR); // Read the file
Size s( pd.source_U8C3.size().width / 1.3, pd.source_U8C3.size().height / 1.3 );
resize( pd.source_U8C3, pd.source_U8C3, s, 0, 0, CV_INTER_AREA );
pd.dim1by1.create(100,800,CV_8UC1);
cout << "source type = " << pd.source_U8C3.type() << endl;
if(! pd.source_U8C3.data ) { cout << "Could not open image" << std::endl; return 0;}
cvtColor(pd.source_U8C3, pd.temp2_U8C3, CV_BGR2HSV); // original to hsv
split(pd.temp2_U8C3, pd.tempv1_U8C1);
namedWindow( "Glare Reduction - Controls", WINDOW_AUTOSIZE ); // Create a window for display.
onProgram6Trackbar1(0,&pd);
createTrackbar("k1", "Glare Reduction - Controls", &(pd.k1), 255, &onProgram6Trackbar1, &pd);
imshow( "Glare Reduction - Controls", pd.dim1by1 ); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
Update 2:
I think I may have found the source of the problem. When add this line
static void onProgram6Trackbar1(int v, void* vp) {
ProgramData * pd = (ProgramData *) vp;
pd->temp3_U8C1 = pd->tempv1_U8C1[2].clone();
inRange(pd->temp3_U8C1, Scalar(pd->k1), Scalar(255), pd->temp4_U8C1);
bitwise_not(pd->temp4_U8C1, pd->temp5_U8C1);
bitwise_and(pd->temp5_U8C1, pd->temp3_U8C1, pd->temp6_U8C1);
pd->temp7_U8C1 = pd->tempv1_U8C1[2].clone(); // <----
bitwise_or(pd->temp6_U8C1, Scalar(pd->k1), pd->temp7_U8C1, pd->temp4_U8C1);
imshow( "Glare Reduction 4", pd->temp7_U8C1);
}
to onProgram6Trackbar1 it suddenly works as expected. I thought since opencv 2 does its own memory allocation I didn't have to initialize pd->temp7_U8C1 which is serving as the output matrix in the call to bitwise_or. It's almost like the underlying memory in pd->temp7_U8C1 was pointing to memory that belonged to one of the buffers that was used as output to the image processing done in main (pd.tempv1_U8C1 or pd.source_U8C3). Either the line I added did something else that I have not thought of.
So my new question is why did this line fix it and what is going on underneath. Is the result of using an uninitialized mat behavior defined somewhere in the documentation? It was my understanding that you don't have to initialize the size or type of a matrix that you are using as an output mat.
maybe a bit too old, anyway: First check the slightly cleaned code. I removed everything that's redundant and send the actual function of the trackbar into a member of your class. This way, you can directly operate on the members.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
class ProgramData
{
public:
ProgramData()
{
k1 = 0;
}
int k1;
Mat source_U8C3,
temp2_U8C3, temp4_U8C1,
temp5_U8C1, temp6_U8C1,
temp7_U8C1;
vector<Mat> tempv1_U8C1;
void reduce_glare(void)
{
// sets elements in temp4 to 255 if within range
inRange(tempv1_U8C1[2], Scalar(k1), Scalar(255), temp4_U8C1);
// bitwise_not(InputArray src, OutputArray dst)
bitwise_not(temp4_U8C1, temp5_U8C1);
// bitwise_and(InputArray src1, InputArray src2, OutputArray dst)
bitwise_and(temp5_U8C1, tempv1_U8C1[2], temp6_U8C1);
// watch out here:
temp7_U8C1 = Mat::ones(tempv1_U8C1[2].size(), CV_8UC1);
Mat x = Mat::ones(tempv1_U8C1[2].size(), CV_8UC1) * k1;
// bitwise_or(InputArray src1, InputArray src2, OutputArray dst, InputArray mask)
bitwise_or(temp6_U8C1, x, temp7_U8C1, temp4_U8C1);
cout << "source type = " << temp7_U8C1.type() << endl;
cout << "source channels = " << temp7_U8C1.channels() << endl;
cout << "source depth = " << temp7_U8C1.depth() << endl;
}
};
void onProgram6Trackbar1(int v, void *vp)
{
ProgramData *pd = static_cast<ProgramData *>(vp);
(*pd).reduce_glare();
imshow("Glare Reduction 4", pd->temp7_U8C1);
}
int main(int argc, char **argv)
{
ProgramData pd;
pd.source_U8C3 = imread("CutDat.jpeg", IMREAD_COLOR);
Size s(pd.source_U8C3.size().width / 1.3, pd.source_U8C3.size().height / 1.3);
resize(pd.source_U8C3, pd.source_U8C3, s, 0, 0, CV_INTER_AREA);
cout << "source type = " << pd.source_U8C3.type() << endl;
cvtColor(pd.source_U8C3, pd.temp2_U8C3, CV_BGR2HSV);
split(pd.temp2_U8C3, pd.tempv1_U8C1);
namedWindow("Glare Reduction - Controls", WINDOW_AUTOSIZE);
imshow("Glare Reduction - Controls", Mat(100, 800, CV_8UC1));
createTrackbar("k1", "Glare Reduction - Controls", &(pd.k1), 255, &onProgram6Trackbar1, &pd);
waitKey(0);
return 0;
}
Important is the line where temp7_U8C1 is initialized, but not with the original data. The result you get is still not want you want, but it highlights that the issue is within the call to bitwise_or. Your question regarding the Scalar bug doesn't apply here as I've shown it in the code.
The code is tested on Windows with 2.4.10 and on Ubuntu 2.4.8 both giving the same results. Testing the code on valgrind runs fine.
I am stuck with the problem while implementing chamfer matching program in OpenCV
https:// code.ros.org/trac/opencv/browser/trunk/opencv/samples/cpp/chamfer.cpp?rev=4194
Following is the code it is reading
template image
and test image
, I am using VS 2008 and OpenCV2.4.6
#include "stdafx.h"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/contrib/contrib.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
IplImage *src;
src = cvLoadImage("C:\\Users\\JOSHI\\Desktop\\Images\\logo_in_clutter.png",1);
Mat img=cvarrToMat(src);
imshow("Mat",img);
src = cvLoadImage("C:\\Users\\JOSHI\\Desktop\\Images\\logo.png",1);
Mat tpl=cvarrToMat(src);
imshow("Mat",tpl);
Mat cimg;
// if the image and the template are not edge maps but normal grayscale images,
// you might want to uncomment the lines below to produce the maps. You can also
// run Sobel instead of Canny.
Canny(img, img, 5, 50, 3);
Canny(tpl, tpl, 5, 50, 3);
vector<vector<Point> > results;
vector<float> costs;
int best = chamerMatching( img, tpl, results, costs );
if( best < 0 )
{
cout << "not found;\n";
return 0;
}
size_t i, n = results[best].size();
for( i = 0; i < n; i++ )
{
Point pt = results[best][i];
if( pt.inside(Rect(0, 0, cimg.cols, cimg.rows)) )
cimg.at<Vec3b>(pt) = Vec3b(0, 255, 0);
}
imshow("result", cimg);
waitKey();
return 0;
}
this is the error image
can you suggest me why I am getting this error as I am new to OpenCV and Image Processing
I had same problem. Solution: http://code.opencv.org/issues/3603
You need to download opencv from source, open the chamfermatching.cpp and comment line:
~Matching()
{
for (size_t i = 0; i<templates.size(); i++) {
//delete templates[i];
}
}
Then you need to rebuild opencv. After this it should work.