Appliquer une matrice 3*3 à image en C++

dj roupe Messages postés 2 Date d'inscription vendredi 22 octobre 2004 Statut Membre Dernière intervention 24 octobre 2004 - 22 oct. 2004 à 16:14
dj roupe Messages postés 2 Date d'inscription vendredi 22 octobre 2004 Statut Membre Dernière intervention 24 octobre 2004 - 24 oct. 2004 à 12:12
Je dispose d'une image définie par un ensemble de pixels et je souhaite appliquer une matrice homogène 3*3 à cette image et je ne sais pas comment faire.

J'accepte tt réponses ou idées sur ce pb.
DJ ROUPE

6 réponses

platon179 Messages postés 237 Date d'inscription lundi 20 mai 2002 Statut Membre Dernière intervention 22 juillet 2011 2
23 oct. 2004 à 09:22
Alors là c'est des opérations matricielles. Matrice 3x3 homogène, c'est à dire en 2D... Voici l'algo pour effectuer une rotation d'un point par une matrice 3x3, en assumant que tes points aient des coordonnées (x, y, z). Ne t'inquiete pas pour le Z en 2D, définis-le juste à 1, c'est pour que les opérations matricielles puissent être exécutées :

o.x = m._11 * p.x + m._21 * p.y + m._31 * p.z
o.y = m._12 * p.y + m._22 * p.y + m._32 * p.z
o.z = m._13 * p.z + m._23 * p.y + m._33 * p.z

Si je me suis pas planté, mais ca devrait ressembler à ca, avec o et p étant des points :

struct Point
{
double x, y, z;
};

et m une matrice de la forme :

struct Matrix
{
double _11, _21, _31;
double _12, _22, _32;
double _13, _23, _33;
};

Voila, en esperant que ca reponde a ta question... :)
Bon codage
0
platon179 Messages postés 237 Date d'inscription lundi 20 mai 2002 Statut Membre Dernière intervention 22 juillet 2011 2
23 oct. 2004 à 09:28
Désolé, coquille dans la formule, ca m'apprendra à taper trop vite... La formule correcte est:

o.x = m._11 * p.x + m._21 * p.y + m._31 * p.z
o.y = m._12 * p.x + m._22 * p.y + m._32 * p.z
o.z = m._13 * p.x + m._23 * p.y + m._33 * p.z
0
plus_plus_fab Messages postés 232 Date d'inscription vendredi 9 janvier 2004 Statut Membre Dernière intervention 8 janvier 2005
23 oct. 2004 à 14:41
que veux-tu dire par appliquer ?
faire une rotation, une translation, une homothetie ?
A ce moment la, une matrice 2x2 suffit, ou alors il y a une composante nulle.

Mais ta question me fait plus penser à un filtrage, cherche sur google le mot clé "produit de convolution". Il faut ensuite dicrétiser cette formule pour l'adapter à une image ...
0
platon179 Messages postés 237 Date d'inscription lundi 20 mai 2002 Statut Membre Dernière intervention 22 juillet 2011 2
23 oct. 2004 à 20:10
Non pour une translation il faut une 3x3, le vecteur déplacement est dans la troisième colonne en haut... Ca sert à ca les coordonnées homogènes... Sinon, c'est vrai, une 2x2 suffirait ;)

Sinon, si tu ne parlais pas de rotations ou de changements d'échelle, j'ai pas compris comme il faut.... :(
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
plus_plus_fab Messages postés 232 Date d'inscription vendredi 9 janvier 2004 Statut Membre Dernière intervention 8 janvier 2005
23 oct. 2004 à 21:20
pour une translation, en fait c'est ni une 2x2 (méa culpa), ni une 3x3, ni meme un produit matriciel,
c'est une somme vectorielle !
une homothétie, c'est y = Ax + b, avec A matrice de rotation et b le vecteur de translation.
y le nouveau vecteur, x l'ancien.

Mais je ne pense pas que ce soit de ça que dj roupe veuille parler ...
0
dj roupe Messages postés 2 Date d'inscription vendredi 22 octobre 2004 Statut Membre Dernière intervention 24 octobre 2004
24 oct. 2004 à 12:12
En fait je parle bien de rotations et de changements d'échelle, mais aussi de distortion. En fros une image que l'on voit "de travers, j'aimerai la voir "droite". Mais mon pb n'est pas de trouver la matrice(car ca je l'ai), mais c de l'intégrer en c ds mon programme(qui n'est pas le mien, c ca le pb). Le .cpp ou je souhaite intéger cette matrice et où est définie mon image est mis ci dessous. Si qqc pouvais m'aider ca serait sympa. Merci

// Scotome_v3Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "Scotome_v3.h"
#include "Scotome_v3Dlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CScotome_v3Dlg dialog

CScotome_v3Dlg::CScotome_v3Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CScotome_v3Dlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CScotome_v3Dlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CScotome_v3Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CScotome_v3Dlg)
DDX_Control(pDX, IDC_APPLICATION1, m_Application1);
DDX_Control(pDX, IDC_SYSTEM1, m_System1);
DDX_Control(pDX, IDC_IMAGE_RECTIFIED, m_Image2);
DDX_Control(pDX, IDC_IMAGE_REAL, m_Image1);
DDX_Control(pDX, IDC_GRAPHICCONTEXT_REAL, m_GraphContext1);
DDX_Control(pDX, IDC_GRAPHICCONTEXT_RECTIFIED, m_GraphContext2);
DDX_Control(pDX, IDC_DISPLAY_REAL, m_Display1);
DDX_Control(pDX, IDC_DISPLAY_RECTIFIED, m_Display2);
DDX_Control(pDX, IDC_DIGITIZER_RECTIFIED, m_Digitizer2);
DDX_Control(pDX, IDC_DIGITIZER_REAL, m_Digitizer1);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CScotome_v3Dlg, CDialog)
//{{AFX_MSG_MAP(CScotome_v3Dlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_CLOSE, OnButtonClose)
ON_BN_CLICKED(IDC_GO_BUTTON, OnGoButton)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CScotome_v3Dlg message handlers

BOOL CScotome_v3Dlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

SetParam.DoModal();

Horizontal = SetParam.m_Horizontal;
Vertical = SetParam.m_Vertical;
switch (SetParam.m_Zoom)
{
case 0:
Zoom = 0.25;
break;
case 1:
Zoom = 1.0/3.0;
break;
case 2:
Zoom = 0.5;
break;
case 3:
Zoom = 1.0;
break;
case 4:
Zoom = 1.5;
break;
case 5:
Zoom = 2.0;
break;
case 6:
Zoom = 2.5;
break;
default:
Zoom = 1.0;
}

// recuperation de la taille de l'image
SizeX = m_Image1.GetSizeX();
SizeY = m_Image1.GetSizeY();

// création ptr
//unsigned char * ptr;
ptr=(unsigned char *)(malloc(SizeX * SizeY));

//unsigned char * ptr2;
ptr2=(unsigned char *)(malloc(SizeX * SizeY));

return TRUE; // return TRUE unless you set the focus to a control
}

void CScotome_v3Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.

void CScotome_v3Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}

// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CScotome_v3Dlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

void CScotome_v3Dlg::OnButtonClose()
{
// Close the dialog box
EndDialog(IDOK);
}

// **************************************************************************
// Fonction principale de traitement de l'image
// **************************************************************************

int CScotome_v3Dlg::ImageProcessing()
{

int GradientX=0;
int GradientY=0;
int NewColor=0;

// m_Digitizer1.GrabContinuous();

// Sleep(2000);

// ClockStart = clock();

counter = 0;

// création COleSafeArray m_UArray
SAFEARRAYBOUND m_rgsabound[1];
COleSafeArray m_UArray;
m_rgsabound[0].lLbound = 0;
m_rgsabound[0].cElements = SizeX*SizeY;
m_UArray.Create(VT_UI1, 1, m_rgsabound);

SAFEARRAYBOUND m_rgsabound2[1];
COleSafeArray m_UArray2;
m_rgsabound2[0].lLbound = 0;
m_rgsabound2[0].cElements = SizeX*SizeY;
m_UArray2.Create(VT_UI1, 1, m_rgsabound2);

//AfxMessageBox("on commence...");

do
{
m_UArray.AllocData();
m_UArray2.AllocData();

m_Digitizer1.Grab();

// m_Image1 -> m_UArray
m_Image1.Get(m_UArray, imFormatDefault, imAllBands, 0, 0, SizeX, SizeY);

// m_UArray -> ptr
m_UArray.AccessData((void **)&ptr);
m_UArray2.AccessData((void **)&ptr2);

column = 2;
do
{
row = 2;
do
{

// calcul de la valeur des pixels origine
rowSrc = INT( (row - (SizeX / 2) - Horizontal) / Zoom + (SizeX / 2) - 0.5 );
columnSrc = INT( (column - (SizeY / 2) - Vertical) / Zoom + (SizeY / 2) - 0.5 );
// test: contour ou non?
if ((rowSrc > 0) && (rowSrc+1 < SizeX) && (columnSrc > 0) && (columnSrc+1 < SizeY))
{
// filtre de Roberts 2 dimensions pour detection de contours
GradientX = ptr[columnSrc*SizeX + rowSrc] - ptr[(columnSrc+1)*SizeX + rowSrc+1];
GradientY = ptr[columnSrc*SizeX + rowSrc+1] - ptr[(columnSrc+1)*SizeX + rowSrc];

// filtre de Prewitt 2 dimensions pour detection de contours
// GradientX = (1.0/3.0)*(-ptr[(columnSrc-1)*SizeX + rowSrc-1] - ptr[(columnSrc-1)*SizeX + rowSrc] - ptr[(columnSrc-1)*SizeX + rowSrc+1] + ptr[(columnSrc+1)*SizeX + rowSrc] + ptr[(columnSrc+1)*SizeX + rowSrc] + ptr[(columnSrc+1)*SizeX + rowSrc+1]);
// GradientY = (1.0/3.0)*(-ptr[(columnSrc-1)*SizeX + rowSrc-1] - ptr[(columnSrc)*SizeX + rowSrc-1] - ptr[(columnSrc+1)*SizeX + rowSrc-1] + ptr[(columnSrc-1)*SizeX + rowSrc+1] + ptr[(columnSrc)*SizeX + rowSrc+1] + ptr[(columnSrc+1)*SizeX + rowSrc+1]);

// filtre de Sobel 2 dimensions pour detection de contours
// GradientX = (1.0/4.0)*(-ptr[(columnSrc-1)*SizeX + rowSrc-1] - 2*ptr[(columnSrc-1)*SizeX + rowSrc] - ptr[(columnSrc-1)*SizeX + rowSrc+1] + ptr[(columnSrc+1)*SizeX + rowSrc] + 2*ptr[(columnSrc+1)*SizeX + rowSrc] + ptr[(columnSrc+1)*SizeX + rowSrc+1]);
// GradientY = (1.0/4.0)*(-ptr[(columnSrc-1)*SizeX + rowSrc-1] - 2*ptr[(columnSrc)*SizeX + rowSrc-1] - ptr[(columnSrc+1)*SizeX + rowSrc-1] + ptr[(columnSrc-1)*SizeX + rowSrc+1] + 2*ptr[(columnSrc)*SizeX + rowSrc+1] + ptr[(columnSrc+1)*SizeX + rowSrc+1]);

NewColor = INT(sqrt(GradientX*GradientX + GradientY*GradientY));
if (NewColor > 20)
{
ptr2[column*SizeX+row] = 255;
}
else
{
// ptr2[column*SizeX + row] = ptr[column*SizeX + row];
}
}
else
{
// ptr2[column*SizeX + row] = ptr[column*SizeX + row];
}
row++;
} while (row < SizeX-1);
column++;
} while (column < SizeY-1);

m_Image2.Put(m_UArray2, imFormatDefault, imAllBands, 0, 0, SizeX, SizeY);

m_UArray.UnaccessData();
m_UArray2.UnaccessData();
counter++;
} while (counter < 100);

//ClockEnd = clock();

//Duree = (ClockEnd - ClockStart)/1000.0;

//CString msg;

//msg.Format("%i images en %2.1f secondes.", counter, Duree);

//AfxMessageBox(msg);

AfxMessageBox("Fin de la période de test.");

// *************** Indice Couleurs ***************

// (0,255,Color) bleu vert
// (255,255,Color) jaune
// (255,0,Color) rose/rouge
// (0,Color,255) bleu
// (255,Color,255) rose
// (255,Color,0) jaune/orange
// (Color,0,255) violet
// (Color,255,255) bleu clair
// (Color,255,0) vert clair
// (Color,0,0) rouge foncé
// (0,Color,0) vert foncé
// (0,0,Color) bleu foncé

// **************** Fin du programme ******************
return 0;
}
// **************************************************************************
// **************************************************************************

void CScotome_v3Dlg::OnGoButton()
{
ImageProcessing();

}

DJ ROUPE
0
Rejoignez-nous