Необходимо написать программу на C++ для перевода из цветовой схемы YUV в HSV. Но для этого сначала необходимо переводить в RGB, а затем в нужную цветовую схему. Я создал свой класс и объект этого класса. Затем пытаюсь присвоить полю этого объекта число. Программа компилируется (пишет что ошибок нет), но при запуске программы после нажатия кнопки перевести выдается ошибка: "Access violation at adress 00401BB1 in module Project1.exe. Write of adress 00000000" Подскажите в чем ошибка? Я не уверен что выложил нужный код, а все файлы нельзя загрузить.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("LAB1V1_9.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
И еще: непонятно, зачем двухстуенчатое преобразование через RGB, если требуется не универсальный конвертер, а лишь преобразование одного наперед заданного формата в другой наперед заданный.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "LAB1V1_9.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
float R=0,G,B;
Hue->Clear();
Saturation->Clear();
Volume->Clear();
R=StrToFloat(Y->Text); //в этой строке ошибка!
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Y->Clear();
U->Clear();
V->Clear();
}
//---------------------------------------------------------------------------
Написал я полностью программу, а она почему-то абсолютно все неправильно считает, хотя делал все по формулам. Ошибка доже при переводе из YUV в RGB, хотя там вроде даже негде ошибиться. Может кто знает в чем проблема? Заранее спасибо!
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <math.h>
#include "LAB1V1_9.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int R,G,B,max,y,u,v;
float Px,Py;
y=StrToInt(Y->Text);
u=StrToInt(U->Text);
v=StrToInt(V->Text);
Hue->Clear();
Saturation->Clear();
Volume->Clear();
R=y+0*u+1.140*v;
G=y-0.396*u-0.581*v;
B=y+2.029*u+0*v;
Okno->Color=RGB(R,G,B);
max=R;
if (G>max) max=G;
if (B>max) max=B;
Volume->Text=IntToStr(max);
Px=R-0.5*(G+B);
Py=sqrt(3)/2*(G-B);
Saturation->Text=IntToStr((int)(sqrt(pow(Px,2)+pow(Py,2))/max));
Hue->Text=IntToStr((int)atan2(Px,Py));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
int R,G,B,h,n,Rh,Gh,Bh,Rs,Gs,Bs;
Y->Clear();
U->Clear();
V->Clear();
h=(StrToInt(Hue->Text)%60)/60;
n=(StrToInt(Hue->Text))/60;
switch (n)
{
case 0: Rh=1; Gh=1-h; Bh=0; break;
case 1: Rh=1-h; Gh=1; Bh=0; break;
case 2: Rh=0; Gh=1; Bh=h; break;
case 3: Rh=0; Gh=1-h; Bh=1; break;
case 4: Rh=h; Gh=0; Bh=1; break;
case 5: Rh=1; Gh=0; Bh=1-h; break;
}
Rs=1*(1-StrToInt(Saturation->Text))+Rh*StrToInt(Saturation->Text);
Gs=1*(1-StrToInt(Saturation->Text))+Gh*StrToInt(Saturation->Text);
Bs=1*(1-StrToInt(Saturation->Text))+Bh*StrToInt(Saturation->Text);
R=Rs*StrToInt(Volume->Text);
G=Gs*StrToInt(Volume->Text);
B=Bs*StrToInt(Volume->Text);
Okno->Color=RGB(R,G,B);
Y->Text=IntToStr((int)(0.299*R+0.587*G+0.114*B));
U->Text=IntToStr((int)(-0.147*R-0.289*G+0.436*B));
V->Text=IntToStr((int)(0.615*R+0.515*G+0.1*B));
}
//---------------------------------------------------------------------------
Подправил программу, но несколько проблем осталось. При переводе из YUV в RGB если ввести максимальные значения из диапазона, т.е. Y=255,U=111,V=157, то получаются значения R=434, G=120, B=573. А значения R и B не входят в диапазон возможных значений схемы RGB. Формулы правильные, то же самое получается если использовать формулы из Википедии. А вторая проблема-неправильно вычисляется компонента H для схемы HSV. Подскажите плиз в чем дело?
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <math.h>
#include "LAB1V1_9.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int R,G,B,max,y,u,v;
float Px,Py;
y=StrToInt(Y->Text);
u=StrToInt(U->Text);
v=StrToInt(V->Text);
Hue->Clear();
Saturation->Clear();
Volume->Clear();
R=abs(y+1.14*v);
G=abs(y-0.396*u-0.581*v);
B=abs(y+2.029*u);
Edit1->Text=FloatToStr®;
Edit2->Text=FloatToStr(G);
Edit3->Text=FloatToStr(B);
Okno->Color=RGB(R,G,B);
max=R;
if (G>max) max=G;
if (B>max) max=B;
Volume->Text=IntToStr(max);
Px=(R-0.5*(G+B));
Py=(sqrt(3)/2*(G-B));
Saturation->Text=IntToStr((int)floor(255*(sqrt(pow(Px,2)+pow(Py,2))/StrToInt(Volume->Text))));
Hue->Text=FloatToStr((atan2(Px,Py))); //вот здесь неправильно вычисляется компонента H
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
float R,G,B,Rh,Gh,Bh,Rs,Gs,Bs,Sat,Vol;
int h, n;
Y->Clear();
U->Clear();
V->Clear();
Sat=(float)StrToInt(Saturation->Text)/255;
Vol=(float)StrToInt(Volume->Text)/255;
h=(StrToInt(Hue->Text)%60)/60;
n=StrToInt(Hue->Text)/60;
switch (n)
{
case 0: Rh=255; Gh=h; Bh=0; break;
case 1: Rh=255-h; Gh=255; Bh=0; break;
case 2: Rh=0; Gh=255; Bh=h; break;
case 3: Rh=0; Gh=255-h; Bh=255; break;
case 4: Rh=h; Gh=0; Bh=255; break;
case 5: Rh=255; Gh=0; Bh=255-h; break;
}
Rs=(Rh-255)*Sat+255;
Gs=(Gh-255)*Sat+255;
Bs=(Bh-255)*Sat+255;
R=Rs*Vol;
G=Gs*Vol;
B=Bs*Vol;
Okno->Color=RGB(R,G,B);
Y->Text=IntToStr((int)floor(0.299*R+0.587*G+0.114*B));
U->Text=IntToStr((int)floor(-0.147*R-0.289*G+0.436*B));
V->Text=IntToStr((int)floor(0.615*R-0.515*G-0.1*B));
}
//---------------------------------------------------------------------------
Неужели никто не знает в чем причина? Если кто знает, подскажите пожалуйста.
1. Твои формулы явно отличаются от приведенных Википедии http://ru.wikipedia.org/wiki/YUV (кстати, если говоришь про внешний источник, приводи точные ссылки, не заставляй людей искать).
2. Откуда взяты значения, которые ты называешь максимальными? Я не спец по цветоделению, как и большинство народа тут, думаю, так что ты приводи побольше инфы, если хочешь получить помощь.
Трудно и неинтересно разговаривать с человеком, который на каждом шагу твердит:
Edit1->Text=FloatToStr®; // <--- Откуда взялась r ???
Edit2->Text=FloatToStr(G);
Edit3->Text=FloatToStr(B);
Okno->Color=RGB(R,G,B);
max=R;
Lapp
До того как я написал что формулы верны, я не знал, что при получении результата, не входящего в диапазон возможных значений, его надо приводить к конкретному числу. И лично я не считаю это частью формулы. Я бы назвал это примечанием.
volvo
1. Не знаю почему буква r отобразилась в нижнем регистре, у меня в программе она в верхнем регистре.
2. К примеру я ввожу значение H=359, S=255, V=255. Жму перевести, получаю значения. Затем жму перевести обратно и получаю H совсем другое. Мне преподаватель написал по этому поводу: "Hue->Text=FloatToStr((atan2(Px,Py)*180/3.14)); - неверно. Необходимо по координатам точки получить угол 0..359,
читай описание atan2, что она получает и что возвращает." Я вроде как и получаю угол, передав функции atan2 координаты нужной точки. Может я не так что-то понимаю?
float atan2(float y, float x);, то есть, первым параметром в любом случае должен быть Y, а вторым - X... Это первое. Второе - мало того, что функция возвращает значение угла в радианах, так еще в интервале от -pi до pi, значит, просто переводом радиан в градусы ты ничего не добьешься, нужно еще преобразовать углы из -180 .. 180 в 0 .. 360. Начерти на бумаге схему, и подумай, как это сделать...
Py=(sqrt(3)/2*(G-B)); // Это у меня компилироваться отказалось., пришлось делать
Py=(sqrt(3.0)/2*(G-B));
Volvo, большое спасибо. На самом деле надо было просто поменять местами Px и Py. Теперь все работает. Спасибо всем кто мне помогал!