Помощь - Поиск - Пользователи - Календарь
Полная версия: Перевод из одной цветовой схемы в другую
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ада и другие языки
Neon6868
Необходимо написать программу на 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;
}
//---------------------------------------------------------------------------


volvo
Цитата
а все файлы нельзя загрузить
А все и не надо. Ты покажи, как работаешь с классом, и определение самого класса.
andriano
И еще: непонятно, зачем двухстуенчатое преобразование через RGB, если требуется не универсальный конвертер, а лишь преобразование одного наперед заданного формата в другой наперед заданный.
Neon6868
Цитата(andriano @ 14.09.2008 15:53) *

И еще: непонятно, зачем двухстуенчатое преобразование через RGB, если требуется не универсальный конвертер, а лишь преобразование одного наперед заданного формата в другой наперед заданный.


Дело в том, что на лекции мы рассматривали только такой способ. Поэтому таким образом и надо сделать программу.

С прошлым вопросом я разобрался - легче использовать обычную переменную. Но при запуске программы после нажатия кнопки перевести выдается ошибка: "is not a valid floating point value" Подскажите плиз в чем дело?

//---------------------------------------------------------------------------

#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();
}
//---------------------------------------------------------------------------

volvo
Цитата
Подскажите плиз в чем дело?
В том, что на момент нажатия кнопки у тебя в Y->Text строка, которая не является правильной записью числа. Особое внимание обрати на DecimalSeparator, это очень часто упускают из виду...
Neon6868
Цитата(volvo @ 15.09.2008 17:17) *

В том, что на момент нажатия кнопки у тебя в Y->Text строка, которая не является правильной записью числа. Особое внимание обрати на DecimalSeparator, это очень часто упускают из виду...


Спасибо, теперь понял. Я вводил число через точку, а надо через запятую smile.gif
Neon6868
Написал я полностью программу, а она почему-то абсолютно все неправильно считает, хотя делал все по формулам. Ошибка доже при переводе из 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));
}
//---------------------------------------------------------------------------
Neon6868
Подправил программу, но несколько проблем осталось. При переводе из 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));
}
//---------------------------------------------------------------------------
Neon6868
Неужели никто не знает в чем причина? Если кто знает, подскажите пожалуйста.
Lapp
1. Твои формулы явно отличаются от приведенных Википедии http://ru.wikipedia.org/wiki/YUV (кстати, если говоришь про внешний источник, приводи точные ссылки, не заставляй людей искать).

2. Откуда взяты значения, которые ты называешь максимальными? Я не спец по цветоделению, как и большинство народа тут, думаю, так что ты приводи побольше инфы, если хочешь получить помощь.
Neon6868
Цитата(Lapp @ 23.09.2008 6:57) *

1. Твои формулы явно отличаются от приведенных Википедии http://ru.wikipedia.org/wiki/YUV (кстати, если говоришь про внешний источник, приводи точные ссылки, не заставляй людей искать).

2. Откуда взяты значения, которые ты называешь максимальными? Я не спец по цветоделению, как и большинство народа тут, думаю, так что ты приводи побольше инфы, если хочешь получить помощь.


Мои формулы правильные, надо было при получении значения больше, чем 255, просто записать 255. Так что с этим разобрался.

Осталось только понять, почему функция atan2 возвращает неправильные значения.
Lapp
Трудно и неинтересно разговаривать с человеком, который на каждом шагу твердит:
Цитата(Neon6868 @ 21.09.2008 16:33) *
Формулы правильные,
Цитата(Neon6868 @ 24.09.2008 16:30) *
Мои формулы правильные,
- хотя тут же говорит обратное:
Цитата(Neon6868 @ 24.09.2008 16:30) *
надо было при получении значения больше, чем 255, просто записать 255.
Ибо это, если оно так, тоже есть часть формулы, если его нет - о какой такой правильности ты говоришь?..

И почему ты с такой легкостью отвергаешь формулы и Вики, сеачала сказав, что они такие же?..
volvo
Цитата(Neon6868 @ 24.09.2008 16:30) *
Осталось только понять, почему функция atan2 возвращает неправильные значения.
atan2 возвращает неправильные значения, когда получает неправильные параметры. Я не знаю, какими тестами ты проверяешь правильность, но если хочешь - приведи значения R, G, B, при которых по-твоему происходит ошибка (не забудь также написать, что ты ожидаешь увидеть в качестве результата).

И не надо говорить, что это не работает для любых исходных данных, потому что:
  1. Мне совсем неинтересно восстанавливать твой проект. Одно дело, когда ты его присоединяешь полностью, и можно откомпилировать и посмотреть, что там творится, а другое дело - что ты выкладываешь какие-то куски, а что там у тебя лежит на форме, как это все называется, как описано в классе формы - это я должен догадаться сам?

    Вот тебе пример:
    Цитата
    Edit1->Text=FloatToStr®; // <--- Откуда взялась r ???
    Edit2->Text=FloatToStr(G);
    Edit3->Text=FloatToStr(B);
    Okno->Color=RGB(R,G,B);
    max=R;

    Процитирован твой же код, если ты не заметил. Так вот, собственно, вопрос: откуда взялся идентификатор r (это при том, что r и R для С++ - то же самое, что для тебя - "черное" и "белое", это тебе не Дельфи). Опечатка? Исправляй... Так и задумывалось? Но тогда я просто не смогу откомпилировать твою программу, поскольку не знаю, что именно задумывалось...
  2. Мне еще меньше интересно бродить по интернету, и искать фразы типа: "значение YUV = ... , тогда HSV = ...", поэтому приводи конкретные значения. Повторяю: чему перед вычислением Px и Py равняются R, G, B и какие значения H, S, V ожидаются...
Neon6868
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 координаты нужной точки. Может я не так что-то понимаю?
volvo
Цитата
Я вроде как и получаю угол, передав функции 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));

Вот пока и все... Экспериментируй smile.gif
Neon6868
Volvo, большое спасибо. На самом деле надо было просто поменять местами Px и Py. Теперь все работает. Спасибо всем кто мне помогал! smile.gif
Lapp
Цитата(Neon6868 @ 27.09.2008 18:04) *
Я бы назвал это примечанием.
Твои "формулы" - это есть функции нескольких переменных. Так? Теперь я тебе задам функцию графиком (извиняюсь за качество рисунка):

Код
      Y|
       +
       |  ______
      1+ /
       |/
-+--+--+--+--+--+
      /|  1     X
     / +
    /  |
   /   +
  /    |

А теперь докажи, что формула У=1.5*Х - это правильная формула для этой функции.. И еще поясни, почему область Х>1 должна идти под "примечанием" smile.gif. Формула для этой функции выглядит так:
Код
      /
     | 1.5*x, if x<1
y = <
     | 1.5, if x>=1
      \

Примечания оставь для УК smile.gif. В математике все пункты определения объекта равноправны. Не привел "примечания" - получил ошибочную функцию.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.