谈一谈分别利用opencv、Qt、matlab动态显示图片的实现

最近遇到一个需要将图片进行动态显示的任务,图片的分辨率是320*2560,最开始的想法就是将图片看成一个320*2560大小的矩阵,然后定义一个320*320大小的小矩阵去遍历大矩阵,然后就用matlab实现了一下,感觉非常简单。

 

clear all
a=imread('E:\temp\r2.png');
b=im2bw(a);
% imwrite(b,'E:\temp\g.bmp');
m=zeros(320,320);
m1=double(b);
for i=1:2560
    if i<=320
       m(321-i,:)=m1(i,:);
    else
        for j=1:320
        m(j,:)=m1(i+j-1,:);            
        end
        p=logical(m);
        imshow(p);
    end
end


为了简化问题将图像进行了二值化,然后进行了遍历,因为,matlab的编程比较方便,所以就用了“:”运算符,但是想了想还是老实的用正经的语法吧

 

 

clear all
a=imread('E:\temp\r2.png');
b=im2bw(a);
% imwrite(b,'E:\temp\g.bmp');
m=zeros(320,320);
m1=double(b);
for k=1:2241
    for i=1:320
        for j=1:320
            
            m(i,j)=m1(i+k-1,j);
           
            
            
        end
    
    
    end
    imshow(m);
    
end

然后思考怎样在opencv中实现这样的想法,了解了IplImage方法可以运用,但是编程实现的时候遇到了问题,就是不能动态命名的问题,就是说我定义的字符串量不能直接转化成CvArr类型的。没有这样的构造函数,确实是这样,查看IplImage的数据结构发现在定义一个IplImage对象的时候已经有了相关的width,height,imageData,widthStep等等的空间,反正我自己是这么强行理解的。那只好把图像切割成16份了分别显示了。

#include "stdafx.h" 
#include  
#include  
#include 
#include 

using namespace std;


int main(int argc, char* argv[])
{
	IplImage *src = cvLoadImage("E:\\temp\\r2.png", 0);
	cvNamedWindow("source", 1);
	cvShowImage("source", src);
	

	int m = src->height;
	int n = src->width;
	int i, j;
	printf("channel = %d", src->nChannels);

	// 分配内存 
	int **p;
	p = new int *[m];
	for (i = 0; i < m; i++)
	{
		p[i] = new int[n];
	}

	
	uchar *ptr;
	for (i = 0; i < m; i++)
	{
		ptr = (uchar*)src->imageData + i*src->widthStep;
		for (j = 0; j < n; j++)
		{
			p[i][j] = (int)*(ptr + j);
		}
	}
	/**************************************/

	
	IplImage *newImg = cvCreateImage(cvSize(320, 320), 8, 1);
	
	
	//*********************第一帧***************************//
	IplImage *copy1 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy1, i, j, p[i][j]);
			}
		}

		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy1);
		cvWaitKey(2000);
		cvReleaseImage(©1);
		
		//*********************第二帧***************************//
		IplImage *copy2 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy2, i, j, p[i + 160][j]);
			}
		}

		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy2);
		cvWaitKey(1000);
		cvReleaseImage(©2);
		//*********************第三帧***************************//
		IplImage *copy3 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy3, i, j, p[i + 160*2][j]);
			}
		}

		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy3);
		cvWaitKey(1000);
		cvReleaseImage(©3);

		//*********************第四帧***************************//
		IplImage *copy4 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy4, i, j, p[i + 160 * 3][j]);
			}
		}

		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy4);
		cvWaitKey(1000);
		cvReleaseImage(©4);


		//*********************第五帧***************************//
		IplImage *copy5 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy5, i, j, p[i +160 * 4][j]);
			}
		}

		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy5);
		cvWaitKey(1000);
		cvReleaseImage(©5);

		//*********************第六帧***************************//
		IplImage *copy6 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy6, i, j, p[i + 160 * 5][j]);
			}
		}

		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy6);
		cvWaitKey(1000);
		cvReleaseImage(©6);


		//*********************第七帧***************************//
		IplImage *copy7 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy7, i, j, p[i + 160 * 6][j]);
			}
		}

		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy7);
		cvWaitKey(1000);
		cvReleaseImage(©7);
		//*********************第八帧***************************//
		IplImage *copy8 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy8, i, j, p[i + 160 * 7][j]);
			}
		}



		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy8);
		cvWaitKey(1000);
		cvReleaseImage(©8);


		//***********************9****************************//
		IplImage *copy9 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy9, i, j, p[i + 160 * 8][j]);
			}
		}



		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy9);
		cvWaitKey(1000);
		cvReleaseImage(©9);

		//*******************************10************************//
		IplImage *copy10 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy10, i, j, p[i + 160 * 9][j]);
			}
		}



		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy10);
		cvWaitKey(1000);
		cvReleaseImage(©10);


		//***********************11*************************//
		IplImage *copy11 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy11, i, j, p[i + 160 * 10][j]);
			}
		}



		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy11);
		cvWaitKey(1000);
		cvReleaseImage(©11);

		//****************************12***********************//
		IplImage *copy12 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy12, i, j, p[i + 160 * 11][j]);
			}
		}



		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy12);
		cvWaitKey(1000);
		cvReleaseImage(©12);

		//************************************13***************************//
		IplImage *copy13 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy13, i, j, p[i + 160 * 12][j]);
			}
		}



		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy13);
		cvWaitKey(1000);
		cvReleaseImage(©13);
		//************************************14**************************************//
		IplImage *copy14 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy14, i, j, p[i + 160 * 13][j]);
			}
		}



		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy14);
		cvWaitKey(1000);
		cvReleaseImage(©14);
		//************************************15*****************************//

		IplImage *copy15 = cvCreateImage(cvGetSize(newImg), 8, 1);


		for (i = 0; i < 320; i++)
		{
			for (j = 0; j < 320; j++)
			{
				cvSetReal2D(copy15, i, j, p[i + 160 * 14][j]);
			}
		}



		// 显示图像副本 
		cvNamedWindow("copy", 1);
		cvShowImage("copy", copy15);
		cvWaitKey(0);
		cvReleaseImage(©15);
		

		

		// 释放图像 
		cvReleaseImage(&src);
		
		cvDestroyAllWindows();

		

		//释放内存 
		for (i = 0; i < m; i++)
			delete[] p[i];
		delete[] p;
	
	

	return 0;

}


显示结果

 

谈一谈分别利用opencv、Qt、matlab动态显示图片的实现_第1张图片

 

但是这种结果真的不是我想要的,真是水平有限啊,但是后来又发现另外一种方法是基于Qt的图片显示的Pixmap方法

 

#include "MyWidget.h"
#include 
#include 
#include 

MyWidget::MyWidget(QWidget *parent)
	: QFrame(parent), m_times(0)

 

	
{
	
	//m_picture.load("c:/qt.jpg");

	m_picture.load("C:\\temp\\r2.png");
	m_timerId = startTimer(60);
	m_pressedNum = 0;
}

MyWidget::~MyWidget()
{

}

// 目标矩形按比例填充到源矩形, 返回实际的target位置
inline QRect scale(QRect source, QRect target)
{
	int target_w = target.width();
	int target_h = target.height();

	int image_w = source.width();
	int image_h = source.height();

	if(image_w <= 0) image_w = 1;
	if(image_h <= 0) image_h = 1;

	int scaled_w = target_w;
	int scaled_h = image_h * target_w / image_w;
	if(scaled_h > target_h)
	{
		scaled_h = target_h;
		scaled_w = target_h * image_w / image_h;
	}

	// 坐在中心
	int x = (target_w - scaled_w)/2;
	int y = (target_h - scaled_h)/2;
	return QRect(x, y, scaled_w, scaled_h);
}

void MyWidget::paintEvent ( QPaintEvent * event )
{
	QPainter painter(this);

	int width = this->width();
	int height = this->height();
	//QRect target (0, 0, width/2, height/2); // 目标矩形
	//QRect target (width/2, height/2, width/2, height/2); // 目标矩形
	QRect target (0,0,width,height); // 目标矩形

	int img_width = m_picture.width();
	int img_height = m_picture.height();
	
	if (m_times < 65)
	{
		
         QRect source(0, m_times*40, img_width, img_height / 8); // 源矩形
		 QRect scaled_target = scale(source, target);

		 painter.drawPixmap(scaled_target, m_picture, source);
		 m_times = m_times + 1;
		
		
	}
        
	return;
		
}
	
 
// 定时器处理函数
void MyWidget::timerEvent(QTimerEvent * event)
{
	// 可以有多个定时器,每个的定时器有不同的处理
	if (event->timerId() == m_timerId&&m_pressedNum % 2 == 1)
	{
		update(); // 重绘
	}
}
void MyWidget::mouseReleaseEvent(QMouseEvent * event)
{
	m_pressedNum = m_pressedNum+1;
}

这是.cpp文件,对应的.h文件

 

 

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include 
#include  //
#include 
#include 
class MyWidget : public QFrame
{
	Q_OBJECT

public:
	MyWidget(QWidget *parent);
	~MyWidget();


private:
	void paintEvent ( QPaintEvent * event );
	void timerEvent(QTimerEvent * event);
	void mouseReleaseEvent(QMouseEvent * event);
private:
	QPixmap m_picture; //
	int m_timerId; // 每个Timer有一个id
	int m_times; // 次数
	int m_pressedNum;
};

#endif // MYWIDGET_H

重写了paintEvent调用定时器来实现的

还增加了鼠标事件,实现点击一次播放,再点击停止,再点击再播放....

 

 

谈一谈分别利用opencv、Qt、matlab动态显示图片的实现_第2张图片

你可能感兴趣的:(opencv,Qt)